[英]How do I initialize an object of std::array<std::array<T, 2>, 2>?
I'm trying to initialize objects of type thing: 我正在尝试初始化类型的对象:
template<typename T>
struct thing : std::array<std::array<T, 2>, 2>
{
};
thing<int> t1 {{ {1,2}, {3,4} }};
I get: 我明白了:
error: no matching function for call to ‘thing<int>::thing(<brace-enclosed initializer list>)’
thing<int> t1 {{{1,2},{3,4}}};
Ditto with 同上
thing<int> t0{{ 1, 2, 3, 4 }};
and several other things. 和其他几件事。
If you're using a C++17 compiler, you're only missing an extra set of braces. 如果您正在使用C ++ 17编译器,那么您只缺少一组额外的大括号。 The following 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 the rules for aggregates to allow base classes, as long as they're public
and non- virtual
. C ++ 17 修改了聚合规则以允许基类,只要它们是public
和非virtual
。
From §11.6.1/1 [dcl.init.aggr] 来自§11.6.1/ 1 [dcl.init.aggr]
An aggregate is an array or a class with 聚合是一个数组或类
(1.1) no user-provided,explicit
, or inherited constructors ([class.ctor]), (1.1)没有用户提供的,explicit
或继承的构造函数([class.ctor]),
(1.2) no private or protected non-static data members ([class.access]), (1.2)没有私有或受保护的非静态数据成员([class.access]),
(1.3) no virtual functions, and (1.3)没有虚函数,和
(1.4) no virtual, private, or protected base classes ([class.mi]). (1.4)没有虚拟,私有或受保护的基类([class.mi])。
The base classes are now considered elements of the aggregate , and can themselves be initialized using list-initialization . 基类现在被认为是聚合的元素 ,并且可以使用列表初始化来初始化 。
The elements of an aggregate are: 聚合的元素是:
(2.1) for an array, the array elements in increasing subscript order, or (2.1)对于一个数组,数组元素按下标顺序增加,或者
(2.2) for a class, the direct base classes in declaration order, followed by the direct non-static data members ([class.mem]) that are not members of an anonymous union, in declaration order. (2.2)对于一个类,声明顺序中的直接基类,然后是声明顺序中不是匿名联合成员的直接非静态数据成员([class.mem])。
C++14, and earlier , version of the answer follows: C ++ 14及更早 版本的答案如下:
std::array
is an aggregate, and the initialization done using a braced-init-list is aggregate initialization. std::array
是一个聚合,使用braced-init-list完成的初始化是聚合初始化。 However, thing
is not an aggregate because it has a base class. 但是, thing
不是聚合,因为它有一个基类。
From §8.5.1/1 [dcl.init.aggr] 来自§8.5.1/ 1 [dcl.init.aggr]
An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3). 聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条), 没有基类 (第10条),没有虚函数(10.3) )。
Thus, aggregate initialization is not going to work. 因此,聚合初始化不起作用。 Depending on what you're attempting to do, you either want to provide a constructor for thing
that takes an std::array<std::array<T, 2>, 2>
argument, and initialize the base subobject 根据您尝试执行的操作,您要么为需要std::array<std::array<T, 2>, 2>
参数的thing
提供构造函数,并初始化基础子对象
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}} }} };
Or have thing
contain the std::array
as a data member. 或者有thing
包含std::array
作为数据成员。 Now thing
is still an aggregate. 现在thing
仍然是一个集合。
template<typename T>
struct thing
{
std::array<std::array<T, 2>, 2> arr;
};
thing<int> t{ {{ {{1,2}}, {{3,4}} }} };
If what you're attempting to do is have thing
be an alias for an array<array<T,2>,2>
, then you don't need either of the above. 如果你正在试图做的是有thing
是一个别名array<array<T,2>,2>
那么你并不需要或者以上。 Use 使用
template<typename T>
using thing = std::array<std::array<T, 2>, 2>;
thing<int> t{{ {{1,2}}, {{3,4}} }};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.