c – std :: array 的嵌套聚合初始化

前端之家收集整理的这篇文章主要介绍了c – std :: array 的嵌套聚合初始化前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
参见英文答案 > When can outer braces be omitted in an initializer list?1个
我想知道,为什么在下面的代码中声明std_arr会产生错误,而c_arr编译得很好:
struct S { int a,b; };

S c_arr[] = {{1,2},{3,4}};  // OK
std::array<S,2> std_arr = {{1,4}};  // Error: too many initializers

std :: array和S都是聚合.从aggregate initialization on cppreference.com开始:

If the initializer clause is a nested braced-init-list (which is not an expression and has no type),the corresponding class member is
itself an aggregate: aggregate initialization is recursive.

为什么std :: array的初始化不能编译?

解决方法

聚合初始化中的大括号在很大程度上是可选的,因此您可以编写:
S c_arr[] = {1,2,3,4};  // OK
std::array<S,2> std_arr = {1,4};  // OK

但是,如果添加大括号,则会使用大括号将其应用于下一个子对象.不幸的是,当你开始嵌套时,这会导致愚蠢的代码有效,而像你这样的合理代码无效.

std::array<S,{2},4}};  // OK

这些都没关系. {1,4}是std_arr的S [2]成员的有效初始化者. {2}没关系,因为它是尝试初始化int,而{2}是一个有效的初始化器. {3,4}被视为S的初始化者,它也是有效的.

std::array<S,4}};  // error

这不合适,因为{1,2}被视为S [2]成员的有效初始化者.剩余的int子对象初始化为零.

然后你有{3,4},但没有更多成员要初始化.

正如评论中指出的那样,

std::array<S,2> std_arr = {{{1,4}}};

也有效.嵌套的{{1,4}}是S [2]成员的初始化者. {1,2}是第一个S元素的初始化. {3,4}是第二个S元素的初始化.

我在这里假设std :: array< S,2>包含S [2]类型的数组成员,它在当前实现中执行,我相信它可能会得到保证,但之前已经涵盖了SO,目前尚未得到保证.

猜你在找的C&C++相关文章