根据C ++ 11标准中的§12.1/ 4,代码不应该编译

时间:2014-01-13 14:28:20

标签: c++ c++11 constructor language-lawyer

§12.1/ 4:及其第一个要点

  

类X的默认构造函数是类X的构造函数   可以不带参数调用。如果       对于类X没有用户声明的构造函数,没有参数的构造函数被隐式声明为默认值(8.4)。一个   隐式声明的默认构造函数是内联的公共成员   它的班级。类X的默认默认构造函数定义为   删除如果:

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

根据这个要点,这个代码片段不应该编译,因为struct A是一个类似联合的类(它包含一个匿名联合),并且它有一个变体成员,B b;具有非平凡性默认构造函数。但是code compiles without a problem in vc++, clang++ and g++

#include <iostream>

struct B { B(): i(10) {} int i; };

struct A
{
    union{ int y = 1; double x; };
    int i;
    A(int j) : i{j} {};
    B b;
    A() = default;
};

int main() {
    A a;
}

1 个答案:

答案 0 :(得分:13)

变体成员

union{ int y = 1; double x; };

并且没有一个具有非平凡的构造函数。

这在§9.5/ 8中定义:

  

9.5联盟[class.union]

     

8 类似于联盟的类是一个联合或具有匿名联合作为直接成员的类。类似联合的类X有一组变体成员。如果X是联合,则其变体成员是非静态数据成员;否则,其变体成员是X成员的所有匿名联合的非静态数据成员。