title: Using constexpr vectors in template parameters (C++20)
body: <p>Recently, I've been playing around with C++20's new <code>constexpr std::vector</code>s (I'm using GCC v12), and have run into a slight problem (this is actually an extension of <a href="https://stackoverflow.com/questions/72496216/builder-patterns-with-vectors-evaluated-at-compile-time-with-consteval">my last question</a>, but I thought it would just be better to make a new one). I've been trying to use <code>constexpr std::vector</code>s as members to a class, but this seems like it doesn't work as you cannot annotate them with <code>constexpr</code> and therefore <code>constexpr</code> functions think they can't be evaluated at compile time, so now I am trying to use template parameters instead, like this:</p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;array&gt;
  
  template&lt;int N, std::array&lt;int, N&gt; arr = {1}&gt;
  class Test
  {
  public:
      constexpr int doSomething()
      {
          constexpr const int value = arr[0];
          return value * 100;
      }
  };
  
  int main()
  {
      Test&lt;10&gt; myTestClass;
      // return the value to prevent it from being optimized away 
      return myTestClass.doSomething();
  }
  </code></pre>
  <p>This results in the expected assembly output (simply returning 100 from main):</p>
  <pre><code>main:
          mov     eax, 100
          ret
  </code></pre>
  <p>However, something like this doesn't work for <code>std::vector</code>s, <em>even though they can be <code>constexpr</code> now!</em></p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;vector&gt;
  
  template&lt;std::vector&lt;int&gt; vec = {1}&gt;
  class Test
  {
  public:
      constexpr int doSomething()
      {
          constexpr const int value = vec[0];
          return value * 100;
      }
  };
  
  int main()
  {
      Test&lt;&gt; myTestClass;
      return myTestClass.doSomething();
  }
  </code></pre>
  <p>This throws this error:</p>
  <pre><code>&lt;source&gt;:3:35: error: 'std::vector&lt;int&gt;' is not a valid type for a template non-type parameter because it is not structural
      3 | template&lt;std::vector&lt;int&gt; vec = {1}&gt;
        |                                   ^
  In file included from /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/vector:64,
                   from &lt;source&gt;:1:
  /opt/compiler-explorer/gcc-12.1.0/include/c++/12.1.0/bits/stl_vector.h:423:11: note: base class 'std::_Vector_base&lt;int, std::allocator&lt;int&gt; &gt;' is not public
    423 |     class vector : protected _Vector_base&lt;_Tp, _Alloc&gt;
        |           ^~~~~~
  &lt;source&gt;: In function 'int main()':
  &lt;source&gt;:17:24: error: request for member 'doSomething' in 'myTestClass', which is of non-class type 'int'
     17 |     return myTestClass.doSomething();
  </code></pre>
  <p>How can I do this with <code>vector</code>s, or is it even possible? And, is it possible to make <code>constexpr</code> members, or not?</p>