数组 <array<int, M> 的列表初始化,N>

List initialization for array<array<int, M>, N>

初始化二维数组时我们可以做

int data[2][2] = {{1, 2}, {3, 4}}; // OK

我们也可以使用

int data[2][2] = {1, 2, 3, 4}; // OK

这是有道理的,因为二维数组仍然是一个连续的内存块。

当使用数组 class 而不是基本类型时,这有效

array<array<int, 2>, 2> data = {1, 2, 3, 4}; // OK

这又是有道理的,因为数组 class 没有任何额外的数据,最终也作为一个连续的内存块结束。

但是二维列表不起作用:

array<array<int, 2>, 2> data = {{1, 2}, {3, 4}}; // Error

我也可以初始化这个

vector<array<int, 2>> data = {{1, 2}, {3, 4}}; // OK

但无论如何找不到初始化:

array<vector<int>, 2> = ????

我的问题是:

这是否有基本的设计原因(我的猜测是与编译时发生的事情和 运行 时发生的事情有关)?或者这只是我正在使用的编译器 (GCC) 的一个实施决定?

std::array没有任何自定义构造函数(如std::vector),它只是包含一个底层数组,在执行聚合初始化时你需要多一个大括号。

array<array<int, 2>, 2> data = {{{{1, 2}}, {{3, 4}}}};
//                             ^                    ^  <- for array<array<int, 2>, 2>
//                              ^                  ^   <- for the underlying array
//                               ^      ^              <- for the 1st array<int, 2>
//                                ^    ^               <- for its underlying array
//                                         ^      ^    <- for the 2nd array<int, 2>
//                                          ^    ^     <- for its underlying array

我们可以省略大括号,因为

array<int, 2> data = {1, 2};
array<array<int, 2>, 2> data = {1, 2, 3, 4};

因为brace elision:

The braces around the nested initializer lists may be elided (omitted), in which case as many initializer clauses as necessary are used to initialize every member or element of the corresponding subaggregate, and the subsequent initializer clauses are used to initialize the following members of the object.

也就是说上面的代码代码写成

array<array<int, 2>, 2> data = {{{1, 2}, {3, 4}}};

array<array<int, 2>, 2> data = {{1, 2}, {3, 4}}; 失败,因为它被解释为:

array<array<int, 2>, 2> data = {{1, 2}, {3, 4}};
//                             ^              ^  <- for array<array<int, 2>, 2>
//                              ^    ^           <- for the underlying array
//                                      ^    ^   <- excess elements; std::array has only one underlying array