C++ 为什么在没有显式默认构造函数的情况下,将另一个结构作为成员包装在联合中的结构不能编译?

C++ 为什么在没有显式默认构造函数的情况下,将另一个结构作为成员包装在联合中的结构不能编译?,c++,constructor,language-lawyer,unions,default-constructor,C++,Constructor,Language Lawyer,Unions,Default Constructor,这就是我所说的关系: struct A{ int i = 1; }; struct B{ union{A a;}; }; void main(){ B b; }; 在这个星座图中,我的编译器(vs2015)抱怨BB::B(void)的默认构造函数被删除了,注意编译器已经生成了B::B: ../test.cpp(155): error C2280: "B::B(void)" : Es wurde versucht, auf eine gelöschte Funktio

这就是我所说的关系:

struct A{
    int i = 1;
};

struct B{
    union{A a;};
};

void main(){
    B b;
};
在这个星座图中,我的编译器(vs2015)抱怨B
B::B(void)
的默认构造函数被删除了,注意编译器已经生成了
B::B

../test.cpp(155): error C2280: "B::B(void)" : Es wurde versucht, auf eine gelöschte Funktion zu verweisen
../test.cpp(152): note: Compiler hat hier "B::B" generiert
(对不起,我无法说服msvc跟我说英语)

这两个代码更改中的任何一个都可以修复它:

struct A{
    int i; //removed initialzation of member to 1
};

我知道添加一个不加任何作用的默认构造函数并不是一个复杂的或令人讨厌的解决方案,但我真的很想知道C++为什么强迫我这样做。

< P>这是因为: 在以下情况下,类X的默认构造函数被定义为已删除:

  • (2.1)X是一个具有变量成员和非平凡默认构造函数的联合,并且X的变量成员没有默认成员初始值设定项

我们可以看到为什么
A
没有一个简单的默认构造函数,从中可以看出:

如果默认构造函数不是用户提供的,并且:
-(3.1)-其类没有虚拟函数(10.6.2)和虚拟 基类(10.6.1)和
-(3.2)没有its的非静态数据成员 类具有默认的成员初始值设定项(10.3),并且
-(3.3)-所有 其类的直接基类具有普通的默认构造函数, 和
-(3.4)-对于其类中的所有非静态数据成员 对于类类型(或其数组),每个这样的类都有一个平凡的 默认构造函数

我们可以从 删除非静态成员初始值设定项可以使程序格式良好

struct A{
    int i ; // no NSDMI
};

struct B{
    union{A a;};
};
形成我们今天的措辞的文件包括以下内容:

我们还改变了隐式声明特殊的方式 联合体的成员函数在以下步骤中生成 方式:如果为定义了一个非平凡的特殊成员函数 工会的任何成员,或工会内部匿名工会的成员 类,该特殊成员函数将被隐式删除(8.4 对于工会或班级。这会阻止编译器尝试 编写它不知道如何编写的代码,并强制 如果需要,程序员可以编写代码。事实上 编译器不能编写这样的函数,没有理由不让 程序员这样做


一个联合只有一个活动成员,如果一个或多个成员不能默认构造,编译器应该如何选择默认激活哪个成员?

你知道这条规则的基本原理吗?如果它不能决定默认激活哪个成员,这是完全合理的。然而,在我的最小示例中,联合中只有一个成员,可以默认构造。在我的实际用例中,我有两个相同类型的变量,这也不会导致逻辑上的问题。@U用户可能认为不值得为一个不太有用的用例指定它。
struct A{
    int i ; // no NSDMI
};

struct B{
    union{A a;};
};