Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

arrays

struct

#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`

like image 470
user15 Avatar asked Sep 18 '26 02:09

user15


1 Answers

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

like image 92
Remy Lebeau Avatar answered Sep 20 '26 16:09

Remy Lebeau