c++arraysstruct

brace elision on struct template doesn't work like std::array


#include <array>

template<class T, int N>
struct X {T array[N];};

int main() {

  using std::array;

  array<int,3> a{1,2,3};   //works
  array<int,3> c{{1,2,3}}; //works
  array        b{1,2,3};   //works
  array        d{{1,2,3}}; //doesn't work

  X<int,3> e{1,2,3};   //works
  X<int,3> f{{1,2,3}}; //works
  X        g{1,2,3};   //doesn't work
  X        h{{1,2,3}}; //works

}

When I create a std::array variable with CTAD (no template arguments), brace elision seems to apply (or is it really brace elision?), but when I do the same with my class (X), it doesn't work.

Also, I can't initialize an std::array with double quotes (since it's supposedly an aggregate with a single member variable inside it, an C-array, wouldn't the double brace work?), while I can do so with the X class.

How can I make the X class behave the same way std::array does regarding initializing it with single brace while not using explicit template arguments?

Compiler: gcc 14.2.1
Flags: -std=c++23 -O2 -DNDEBUG`


Solution

  • If you add a deduction quide to your struct, then g will work and h will fail, same as std::array. For example:

    template<class T, int N>
    struct X {T array[N];};
    
    // This is based on the actual deduction guide use by
    // Dinkumware for its std::array implementation...
    template <class T, class... Others,
              class = std::enable_if_t<(std::is_same_v<T, Others> && ...)>
              >
    X(T, Others...) -> X<T, 1 + sizeof...(Others)>;
    

    Online Demo