title: Are static constinit member variables identical to non-type template parameters?
body: <p>I have a class template for an N-dimensional array:</p>
  <pre class="lang-cpp prettyprint-override"><code>template&lt;typename T, std::size_t... Shape&gt;
  class ndarray { ... };
  </code></pre>
  <p>One consequence of this template design is that there is an additional 'implicit' template parameter if you will: <code>std::size_t Size</code>, the product of all arguments in <code>Shape</code>. I have been using a C++17 fold expression (<code>(1 * ... * Shape)</code>) where I would typically use <code>Size</code> if it weren't dependent on <code>Shape</code>, but I'm wondering if adding the following 'alias' would result in any subtle differences in the compiled assembly:</p>
  <pre class="lang-cpp prettyprint-override"><code>template&lt;typename T, std::size_t... Shape&gt;
  class ndarray {
      static constinit std::size_t Size = (1 * ... * Shape);
      ...
  };
  </code></pre>
  <p>Interestingly, the ISO C++20 standard doesn't state whether or not <code>constinit</code> implies <code>inline</code> as it does for <code>constexpr</code> and <code>consteval</code>. I think the semantics of <code>constinit</code> (especially in relation to <code>constexpr</code> variables) only really makes sense if the variable were also <code>inline</code>, but its omission from the standard makes me wary of this conclusion.</p>