c++ - C++14 中的聚合成员初始化

标签 c++ aggregate c++14 member-initialization

具有这样的结构:

struct A {
    struct B {
        int a = 21;
        int b;
        int c = 22;
        int d;
        int e = 23;
    };
    B b1  = { 11, 12 };
    B b2  = { 11, 12, 13 };
    int x;
};

并声明:

A a = { { 1, 2, 3, 4 }, { 1 }, 5 };

根据 Clang (3.8.0) 和 GCC (5.4.0),这些是 8 种可能组合的值(a.b1.e 和 a.b2.a 是重复的情况),关于初始位置值取自(或不取自):

a.b1.a = 1   // 111
a.b1.b = 2   // 110
a.b1.c = 3   // 101
a.b1.d = 4   // 100
a.b2.b = 0   // 010    // Why not 12 instead of  0? -> Explained in N3605
a.b2.c = 22  // 011    // Why not  0 instead of 22 ?  Why not 13 ?
a.b2.d = 0   // 000
a.b2.e = 23  // 001    // Why not  0 instead of 23 ?

考虑到 N3605 中的示例和 C++14 标准 (ISO/IEC 14882:2014),第 8.5.1 节,第 7 段:

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).

我假设案例 010 是正确的。那么,为什么案例 011 (a.b2.c) 和 001 (a.b2.e) 不也等于零?案例 010 为零,因为 a.b2“确实有一个初始值设定项”,因此“非静态数据成员初始值设定项被忽略”(再次为 N3605)。为什么不忽略默认成员初始值设定项?

事实上,阅读 C++14 标准引述对我来说更有意义的是 case 010 是 12(它是零)而 case 011 和 001 是零(因为它们实际上是)。所以我不明白的是为什么 a.b2 有时被认为是“有一个初始化程序”而其他时候却不是。

最佳答案

您声明 a 及其所有成员的初始值设定项:b1b2x。这意味着我们构建得好像

a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 1 };
a.x = 5;

B 的定义是 B{ 1, 2, 3, 4 } 表示 B{ 1, 2, 3, 4, 23 } B{ 1 } 表示 B{ 1, 0, 22, 0, 23 }。这正是您得到的结果。


如果你写过

A a = { { 1, 2, 3, 4 }, };

然后 a.b2 将使用其默认值 { 11, 12 } 进行初始化:

a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 11, 12 };
a.x = {};

将示例中的那些大括号表达式(例如 { 1 }{ 11, 12 } 视为完全构造的 B 可能会有所帮助 对象,早在 A 的构造函数甚至看到它们之前。

关于c++ - C++14 中的聚合成员初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41573959/

相关文章:

mysql - SQL 一对多 JOIN/聚合

c++ - 按类型访问具有重复类型的 std::tuple 应该会产生编译错误

c++ - 如何使我的 sizeof sum 结构与空参数包一起工作

c++ - 我相信 clang 错误地允许内联友元函数访问封闭范围内的数据。 gcc 和 vs2013 都拒绝此代码

apache-spark - Spark : What is the difference between Aggregator and UDAF?

sql - 根据另外两个表的计数创建一个指标表

c++ - 如何将片段着色器仅应用于 OpenGL 中的一个对象?

C++11 cin 输入验证

C++11:当定义移动构造函数时,按值返回对象不会抛出异常吗?

c++ - 用 CGAL 编译一个简单的测试