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

AFAIK, the code below shouldn't compile, but it does in clang and GCC. What am I missing here?

下面的代码显示了一个类似联合的 class 和一个非平凡的默认构造函数(成员 y 使用 brace-or-equal-initializer),因此如果默认构造函数 class,则应根据 §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 不是 类并集 class .我刚刚知道 C++11 中的 §9.5/8 说:

A union-like class is a union or a class that has an anonymous union as a direct member. A union-like class X has a set of variant members. If X is a union its variant members are the non-static data members; otherwise, its variant members are the non-static data members of all anonymous unions that are members of X.

现在,考虑下面的片段。它无法编译,因为联合的默认构造函数已被删除。但我仍然不知道 §12.1/5 中的哪个要点对这个结果负责。请再次注意,联合不是 类联合 class,因此,§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';
}

子弹是

X is a union-like class that has a variant member with a non-trivial default constructor

解析为

X is a union-like class that has (a variant member with a non-trivial default constructor)

即 "with a non-trivial default constructor" 适用于变体成员的类型,而不是 X