下面的代码显示了一个类似联合的类,其中包含一个非平凡的默认构造函数(成员y
使用大括号或等于初始化程序进行初始化),因此如果是默认值这类的构造函数是默认的,应根据§12.1/ 5第一个要点删除它。也就是说,声明T t;
不应该编译,因为union T
没有默认构造函数。但是clang和GCC中的code compiles and executes。
#include <iostream>
union T
{
int y{1};
float x;
char c;
T() = default;
};
int main()
{
T t;
std::cout << t.y << '\n';
}
编辑
我的上述问题从一开始就是错误的,因为联盟T 不 类似联盟的类。我刚刚了解了C ++ 11中的§9.5/ 8,其中说:
类似于联盟的类是具有匿名联合的联合或类 作为直接会员。类似联合的类X有一组变体成员。 如果X是联合,则其变体成员是非静态数据成员; 否则,其变体成员是所有的非静态数据成员 作为X成员的匿名工会。
现在,请考虑下面的代码段。它不会编译,因为会删除union的默认构造函数。但我仍然,不知道§12.1/ 5中哪个要点对这个结果是负责任的。请注意,union再次不是类似于union的类,因此,§12.1/ 5中的第一个要点不适用。但这就是clang和GCC中的错误消息。请参阅live example。
#include <iostream>
union T{
int y;
struct A{ int i; A():i{1} {} } a;
};
int main()
{
T t;
std::cout << t.a.i << '\n';
}
答案 0 :(得分:11)
子弹是
X
是一个类似联合的类,其变体成员具有非平凡性 默认构造函数
被解析为
X
是一个类似联盟的类,具有(一个非平凡的变体成员) 默认构造函数)
即,“使用非平凡的默认构造函数”适用于变体成员的类型,而不是X
。