【发布时间】:2015-02-20 19:02:50
【问题描述】:
下面的代码显示了一个类似联合的类,它具有一个重要的默认构造函数(成员 y 使用 brace-or-equal-initializer 进行初始化),所以如果一个默认构造函数用于这样的类是默认的,应该根据 §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 成员的匿名工会。
现在,考虑下面的 sn-p。它无法编译,因为联合的默认构造函数已被删除。但我仍然不知道 §12.1/5 中的哪个要点对这个结果负责。请注意,联合不是 类似联合的类,因此第 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';
}
【问题讨论】:
-
"一个默认构造函数被默认且未定义为已删除,在它被 od-rused 时隐式定义" 因为你的构造函数看起来是 odr-used,它不应该是有效代码吗?跨度>
-
它也可以为 VS 2015 Preview 编译而没有问题。
-
无法以任何方式实例化的联合的目的是什么?
标签: c++ c++11 language-lawyer