如何初始化std :: array <std :: array <T,2>,2>的对象?

ems*_*msr 5 c++ initialization c++11 list-initialization

我正在尝试初始化类型的对象:

template<typename T>
  struct thing : std::array<std::array<T, 2>, 2>
  {
  };

thing<int> t1 {{ {1,2}, {3,4} }};
Run Code Online (Sandbox Code Playgroud)

我明白了:

 error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’
 thing<int> t1 {{{1,2},{3,4}}};
Run Code Online (Sandbox Code Playgroud)

同上

thing<int> t0{{ 1, 2, 3, 4 }};
Run Code Online (Sandbox Code Playgroud)

和其他几件事.

Pra*_*ian 9

如果您正在使用C++ 17编译器,那么您只缺少一组额外的大括号.以下编译:

thing<int> t1 { { { {1,2}, {3,4} } } };
//            | | | |- braces for inner array
//            | | |--- braces for outer array
//            | |----- braces for base sub object of thing
//            |------- braces for list initialization of thing
Run Code Online (Sandbox Code Playgroud)

C++ 17 修改了聚合规则以允许基类,只要它们public是非基类virtual.

来自§11.6.1/ 1 [dcl.init.aggr]

的聚集体是一个数组或与类
(1.1)没有用户提供的,explicit或遗传构造([class.ctor]),
(1.2)无私有或保护非静态数据成员([class.access]),
(1.3)没有虚函数,
(1.4)没有虚拟,私有或受保护的基类([class.mi]).

基类现在被认为是聚合的元素,并且可以使用列表初始化进行初始化.

聚合的元素是:
(2.1)表示数组,数组元素按增加的下标顺序,或
(2.2)表示类,直接基类按声明顺序,后跟直接非静态数据成员([类] .mem])不是匿名联盟的成员,按声明顺序.


C++ 14及更早版本的答案如下:

std::array是一个聚合,使用braced-init-list完成的初始化是聚合初始化.但是,thing它不是聚合,因为它有一个基类.

来自§8.5.1/ 1 [dcl.init.aggr]

的骨料是没有用户提供的构造的阵列或一个类(第9节)(12.1),无私有或保护非静态数据成员(第11),没有基类(第10节),并且没有虚拟功能(10.3 ).

因此,聚合初始化不起作用.根据您尝试执行的操作,您要么提供构造函数thing,以获取std::array<std::array<T, 2>, 2>参数,并初始化基础子对象

template<typename T>
struct thing : std::array<std::array<T, 2>, 2>
{
    thing(std::array<std::array<T, 2>, 2> arr) 
    : std::array<std::array<T, 2>, 2>(arr) 
    {}
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };
Run Code Online (Sandbox Code Playgroud)

或者thing包含std::array作为数据成员.现在thing仍然是一个聚合.

template<typename T>
struct thing
{
    std::array<std::array<T, 2>, 2> arr;
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };
Run Code Online (Sandbox Code Playgroud)

如果您尝试做的是thinga的别名array<array<T,2>,2>,那么您不需要上述任何一个.使用

template<typename T>
using thing = std::array<std::array<T, 2>, 2>;

thing<int> t{{ {{1,2}}, {{3,4}} }};
Run Code Online (Sandbox Code Playgroud)