我试图初始化类型的对象:
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 }};
以及其他一些事情。
答案 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
。
聚合是一个数组或具有
的类 (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}} }};