C++ 在C+中聚合成员初始化+;14
具有这种结构:C++ 在C+中聚合成员初始化+;14,c++,aggregate,c++14,member-initialization,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.
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为重复情况)的值,关于初始值的取值(或不取值):
考虑到C++14标准(ISO/IEC 14882:2014)第8.5.1节第7段中的示例:
如果列表中的初始值设定项子句少于聚合中的成员,则未明确初始化的每个成员应使用大括号或同等初始值设定项进行初始化,如果没有大括号或同等初始值设定项,则使用空初始值设定项列表(8.5.4)进行初始化
我想情况010是正确的。那么,为什么情况011(a.b2.c)和001(a.b2.e)也不等于零呢?案例010为零,因为a.b2“确实有一个初始值设定项”,因此“忽略非静态数据成员初始值设定项”(再次)。为什么默认成员初始值设定项也不被忽略
事实上,阅读C++14的标准引用,我觉得情况010应该是12(它是零),情况011和001应该是零(实际上是零)。所以我不明白的是为什么a.b2有时被认为是“有一个初始值设定项”,而其他时候则不是。在这个例子中,
{1,2,3,4}
是b1的初始值设定项。编译器已经有了一个初始值设定项,因此现在它将不再查看{11,12}
。您声明a
,并为其所有成员使用初始值设定项:b1
,b2
和x
。这意味着我们的构造就像
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
的构造函数甚至还没有看到它们。用{1}
替换了{11,12,13}
。内部默认初始值设定项仍然适用,除非init列表覆盖它们(发生在b2.a
,但不发生在b2.c
和b2.e
)。谢谢@Toby。然而,出现了另一个问题。如果我声明A代码>,a.x是否已初始化?我检查、测试并理解了所有其他案例(aaa={};aaa={{};
,等等),但我发现了不同的答案和来源代码>。假设结构A{}
是在全局名称空间中定义的,它应该是一个静态存储对象,因此应该初始化它(C++14标准3.6.2);否则,自动存储是一个不确定的值。但是,Clang会输出一个随机值(GCC会将a.x初始化为零)。如果定义仅为struct A{int x;}代码>GCC说它是未定义的,叮当声输出0。@JL,我认为A
使a.x
不确定(不像你说的那样,a={};
),但不要只相信我,如果还没有得到回答,请问另一个问题。顺便说一句,不确定值可能是0。。。
a.b1 = B{ 1, 2, 3, 4 };
a.b2 = B{ 11, 12 };
a.x = {};