J L*_*J L 3 c++ aggregate member-initialization c++14
有这个结构:
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;
};
Run Code Online (Sandbox Code Playgroud)
并声明:
A a = { { 1, 2, 3, 4 }, { 1 }, 5 };
Run Code Online (Sandbox Code Playgroud)
根据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 ?
Run Code Online (Sandbox Code Playgroud)
考虑到N3605和C++ 14标准(ISO/IEC 14882:2014)中的示例,第8.5.1节,第7段:
如果列表中的initializer-clause少于聚合中的成员,那么未明确初始化的每个成员都应从其brace-or-equal-initializer初始化,或者如果没有bra-or-equal-initializer,从空的初始化列表(8.5.4).
我假设案例010是正确的.那么,为什么情况011(a.b2.c)和001(a.b2.e)也不等于零?情况010为零,因为a.b2"确实具有初始化器",因此"忽略非静态数据成员初始化器"(再次为N3605).为什么不忽略默认成员初始值设定项?
事实上,阅读C++ 14标准引用它对我来说更有意义的情况是010将是12(它是零)并且情况011和001将是零(实际上是它们).所以我不明白为什么a.b2有时被认为是"有一个初始化器",有时则不是.
声明a与初始化为它的所有成员:b1,b2和x.这意味着我们就好像构建一样
a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 1 };
a.x = 5;
Run Code Online (Sandbox Code Playgroud)
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 }, };
Run Code Online (Sandbox Code Playgroud)
然后a.b2将使用其默认值{11,12}进行初始化:
a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 11, 12 };
a.x = {};
Run Code Online (Sandbox Code Playgroud)
它可以帮助想那些括号表达式,如{ 1 }和{ 11, 12 }在你的例子为完全构造的B对象,很久以前A的构造,甚至看到他们.
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |