AFAIK,下面的代码不应该编译,但它在clang和GCC中.我在这里错过了什么?

Ayr*_*osa 6 c++ language-lawyer c++11

下面的代码显示了一个类似联合的类,其中包含一个非平凡的默认构造函数(y使用大括号或大小写初始化成员),因此如果默认构造函数是默认构造函数,则应根据§删除它12.1/5第一个要点.也就是说,声明T t;不应该编译,因为没有默认的构造函数union T.但是代码在clang和GCC中编译和执行.

#include <iostream>
union T
{
    int y{1};
    float x;
    char c;
    T() = default;
};

int main()
{
    T t;
    std::cout << t.y << '\n';
}
Run Code Online (Sandbox Code Playgroud)

编辑

我的上述问题从一开始就是错误的,因为工会T 不是一个类似工会的阶级.我刚刚了解了C++ 11中的§9.5/ 8,它说:

工会状类是联合或具有匿名联合作为直接成员的类.类似联合的类X具有一组变体成员.如果X是联合,则其变体成员是非静态数据成员; 否则,其变体成员是作为X成员的所有匿名联合的非静态数据成员.

现在,请考虑下面的代码段.它不会编译,因为会删除union的默认构造函数.但我仍然,不知道§12.1/ 5中哪个要点对这个结果是负责任的.请注意,union不是类似联合的类,因此,§12.1/ 5中的第一个要点不适用.但这就是clang和GCC中的错误消息.查看实例.

#include <iostream>

union T{
    int y;
    struct A{ int i; A():i{1} {} } a;
};

int main()
{
    T t;
    std::cout << t.a.i << '\n';
}
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 11

子弹是

X 是一个类似联合的类,它有一个带有非平凡构造函数的变量成员

被解析为

X 是一个类似联合的类(具有非平凡的默认构造函数的变体成员)

即,"使用非平凡的默认构造函数"适用于变体成员的类型,而不是X.

  • @Ayrosa`y`是一个`int`,它像所有原始类型一样没有构造函数.更不用说非平凡的构造函数了.定义`int y {1};`中的*brace-or-equal-initializer*`{1}`不是`y`的构造函数,它用于在*union的*构造函数中初始化`y`提供其他初始化程序.换句话说,`{1}`的存在意味着你的`T()= default;`与`T():y {1} {}`具有相同的效果. (4认同)