有这个结构:
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 段中的示例:
如果列表中的初始化子句少于聚合中的成员,则每个未显式初始化的成员都应从其大括号或相等初始化器初始化,或者,如果没有大括号或相等初始化器,从一个空的初始化列表(8.5.4)。
我认为案例 010 是正确的。那么,为什么情况011(a.b2.c)和001(a.b2.e)也不等于0呢?情况 010 为零,因为 a.b2 “确实有一个初始化程序”,因此“忽略了非静态数据成员初始化程序”(再次N3605)。为什么默认成员初始化器也不会被忽略?
事实上,阅读 C++14 标准引用对我来说更有意义的是,案例 010 将是 12(它为零),而案例 011 和 001 将是零(实际上是)。所以我不明白为什么 a.b2 有时被认为是“有一个初始化程序”,而其他时候却不是。