为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
Why does a struct, that has another struct wrapped in a union as a member not compile without an explicit 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 Funktion zu verweisen
../test.cpp(152): note: Compiler hat hier "B::B" generiert
(对不起,我无法说服msvc和我说英语(
这两个代码更改中的任何一个都可以修复它:
struct A{
int i; //removed initialzation of member to 1
};
或
struct B{
B(){} //adding explicit default constructor
union{A a;};
};
我知道添加一个什么都不做的默认构造函数并不是一个复杂或令人讨厌的解决方法,但我真的想知道C++为什么强迫我这么做。
这是因为[class.default.cctor]p2说:
类X的默认构造函数被定义为已删除,如果:
- (2.1(X是一个并集,它有一个带有非平凡默认构造函数的变体成员
。。。。。
我们可以看到为什么A
没有一个来自[class.default.cctor]p3的琐碎默认构造函数,它说:
如果默认构造函数不是用户提供的,并且如果:
-(3.1(-其类没有虚拟函数(10.6.2(和虚拟基类(10.6.1(,并且
-(3.2(-其没有非静态数据成员类有一个默认的成员初始值设定项(10.3(,并且
-(3.3(-所有其类的直接基类具有琐碎的默认构造函数,和
-(3.4(-对于其类中的所有非静态数据成员对于类类型(或其数组(,每个此类都有一个平凡的默认构造函数。
我们可以从这个活的godbolt示例中看到删除非静态成员初始值设定项可以使程序格式良好。
struct A{
int i ; // no NSDMI
};
struct B{
union{A a;};
};
形成我们今天措辞的文件是2244:1无限制工会(修订版2(,它涵盖了这里的理性:
我们还更改了隐式声明特殊的方式工会的成员函数生成如下方法:如果为工会的任何成员,或类,则该特殊成员函数将被隐式删除(8.4¶10(。这会阻止编译器尝试编写它不知道如何编写的代码,并强制如果需要的话,程序员可以编写代码。事实上编译器不能编写这样的函数。没有理由不让程序员这样做。
一个联合只有一个活动成员,如果不能默认构造一个或多个成员,编译器应该如何选择默认激活哪个成员?
- 如何循环打印顶点结构
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 预处理器:插入结构名称中的前一个行号
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 孤立代码块在结构中引发异常
- 有什么方法可以遍历结构吗
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 无法将结构注册为增强几何体3D点
- 多成员Constexpr结构初始化
- C++将文本文件中的数据读取到结构数组中
- 如何重构类层次结构以避免菱形问题
- 如何在C++中序列化结构数据
- std::memcpy结构,具有TriviallyCopyable类型T的紧密封装成员到T的数组,反之亦然
- 强制C++结构紧密封装
- 使用并集(封装在结构中)来绕过氖数据类型的转换
- 封装与结构——这被认为是糟糕的风格吗
- 在ARM上的c++结构成员对齐和封装要求
- 为可维护性和封装构建c++类层次结构