【问题标题】:List initialization for array<array<int, M>, N>array<array<int, M>, N> 的列表初始化
【发布时间】:2021-09-27 13:49:50
【问题描述】:

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

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, 2, 3, 4}; // OK

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

但是二维列表不起作用:

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&lt;std::array&lt;int, 2&gt;, 2&gt; a = {{{1, 2}, {3, 4}}}; 你需要使用双括号初始化。
  • 编辑: 2 维和 3 维示例:ideone.com/ugs1E6 > 1 维需要双括号初始化。这是在CWG 1270 revision 之前,我从这里给出的示例中读到:en.cppreference.com/w/cpp/container/array 显然它曾经是一维所必需的。
  • vector 有一个显式构造函数,所以如果你有一个向量数组,你必须为每个子元素写出vector{1, 2}

标签: c++ arrays vector stl list-initialization


【解决方案1】:

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:

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

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

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

array&lt;array&lt;int, 2&gt;, 2&gt; 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-05
    • 2013-02-07
    • 1970-01-01
    • 2012-02-10
    • 2013-08-20
    相关资源
    最近更新 更多