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

时间:2017-01-10 16:46:26

标签: 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段:

  

如果列表中的 initializer-clauses 少于聚合中的成员,那么未显式初始化的每个成员都应从其 brace-or-equal-initializer <初始化< / em>或者,如果没有 brace-or-equal-initializer ,则从空的初始化列表(8.5.4)开始。

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

事实上,阅读C ++ 14标准引用它对我来说更有意义的情况是010将是12(它是零)并且情况011和001将是零(实际上是它们)。所以我不明白为什么a.b2有时被认为是&#34;有一个初始化器&#34;有时则不是。

2 个答案:

答案 0 :(得分:6)

您使用其所有成员的初始值设定项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对象可能会有所帮助39; s构造函数甚至看到它们。

答案 1 :(得分:2)

在此示例中,{1, 2, 3, 4}B b1的初始值设定项。编译器已经有一个初始化器,所以现在它不再看{ 11, 12 }了。