array<array<int, M>, N>

问题描述

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

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

我们也可以使用

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

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

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

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

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

但是二维列表不起作用:

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

我也可以初始化这个

vector<array<int,2>> data = {{1,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>
//                              ^                  ^   <- 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,3,4};

因为brace elision

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

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

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...