如何初始化std :: array的对象<std :: array <t,2 =“”>,2&gt;?</std :: array <t,>

时间:2014-07-25 14:30:47

标签: c++ c++11 initialization list-initialization

我试图初始化类型的对象:

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

thing<int> t1 {{ {1,2}, {3,4} }};

我明白了:

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

同上
thing<int> t0{{ 1, 2, 3, 4 }};

以及其他一些事情。

1 个答案:

答案 0 :(得分:9)

如果您使用的是C ++ 17编译器,那么您只缺少一组额外的大括号。以下compiles

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

C ++ 17 modified聚合规则允许基类,只要它们是public和非virtual

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

  

聚合是一个数组或具有
的类       (1.1)       没有用户提供的,explicit或继承的构造函数([class.ctor]),
      (1.2)       没有私有或受保护的非静态数据成员([class.access]),
      (1.3)       没有虚函数,和
      (1.4)       没有虚拟,私有或受保护的基类([class.mi])。

基类现在被视为elements of the aggregate,并且可以使用 list-initialization 进行初始化。

  

汇总的元素是:
      (2.1)       对于数组,数组元素按下标顺序增加,或者为       (2.2)       对于类,声明顺序中的直接基类,后跟声明顺序中不是匿名联合成员的直接非静态数据成员([class.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}} }} };

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

template<typename T>
struct thing
{
    std::array<std::array<T, 2>, 2> arr;
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };

如果您尝试做的是将thing作为array<array<T,2>,2>的别名,那么您不需要上述任何一项。使用

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

thing<int> t{{ {{1,2}}, {{3,4}} }};