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

Sca*_*let 3 c++ arrays stl vector list-initialization

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

int data[2][2] = {{1, 2}, {3, 4}}; // OK
Run Code Online (Sandbox Code Playgroud)

我们也可以使用

int data[2][2] = {1, 2, 3, 4}; // OK
Run Code Online (Sandbox Code Playgroud)

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

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

array<array<int, 2>, 2> data = {1, 2, 3, 4}; // OK
Run Code Online (Sandbox Code Playgroud)

这又是有道理的,因为数组类没有任何额外的数据,并且最终也成为了一块连续的内存。

但是二维列表不起作用:

array<array<int, 2>, 2> data = {{1, 2}, {3, 4}}; // Error
Run Code Online (Sandbox Code Playgroud)

我也可以初始化这个

vector<array<int, 2>> data = {{1, 2}, {3, 4}}; // OK
Run Code Online (Sandbox Code Playgroud)

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

array<vector<int>, 2> = ????
Run Code Online (Sandbox Code Playgroud)

我的问题是:

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

son*_*yao 6

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
Run Code Online (Sandbox Code Playgroud)

我们可以省略大括号作为

array<int, 2> data = {1, 2};
array<array<int, 2>, 2> data = {1, 2, 3, 4};
Run Code Online (Sandbox Code Playgroud)

因为大括号省略

嵌套初始化器列表周围的大括号可以省略(省略),在这种情况下,根据需要使用尽可能多的初始化器子句来初始化相应子聚合的每个成员或元素,随后的初始化器子句用于初始化以下成员目的。

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

array<array<int, 2>, 2> data = {{{1, 2}, {3, 4}}};
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)