Why do unions have a deleted default constructor if just one of its members doesn#39;t have one?(如果联合中只有一个成员没有,为什么联合有一个已删除的默认构造函数?)
问题描述
N3797::9.5/2 [class.union]
说:
如果联合的任何非静态数据成员具有非平凡的默认值构造函数(12.1),复制构造函数(12.8),移动构造函数(12.8),复制赋值运算符 (12.8)、移动赋值运算符 (12.8) 或析构函数(12.4),union对应的成员函数必须由用户提供,否则将被隐式删除 (8.4.3)联合
If any non-static data member of a union has a non-trivial default constructor (12.1), copy constructor (12.8), move constructor (12.8), copy assignment operator (12.8), move assignment operator (12.8), or destructor (12.4), the corresponding member function of the union must be user-provided or it will be implicitly deleted (8.4.3) for the union
我试图通过示例来理解该注释:
I was trying to understand that note by example:
#include <iostream>
#include <limits>
struct A
{
A(const A&){ std::cout << "~A()" << std::endl; } //A has no default constructor
};
union U
{
A a;
};
U u; //error: call to implicitly-deleted default constructor of 'U'
int main()
{
}
演示
我不太清楚这种行为.struct A
没有隐式声明的默认构造函数,因为 12.1/4: [class.ctor]
说:
That behavior isn't quite clear to me. struct A
doesn't have implicitly-declared default constructor, because 12.1/4: [class.ctor]
says:
如果类 X 没有用户声明的构造函数,一个构造函数没有参数被隐式声明为默认值 (8.4).
If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4).
这意味着 struct A
没有非平凡的默认构造函数(根本没有默认构造函数,特别是非平凡的).那是 union U
不必删除默认构造函数.怎么了?
Which means struct A
doesn't have a non-trivial default constructor (There is no default constructor at all, in particular non-trivial). That's union U
doesn't have to have a deleted default constructor. What's wrong?
推荐答案
相关措辞在 C++11 [class.ctor]p5(强调我的):
The relevant wording is in C++11 [class.ctor]p5 (emphasis mine):
类 X
的默认构造函数是类 X
的构造函数,可以不带参数调用.如果类 X
没有用户声明的构造函数,则没有参数的构造函数被隐式声明为默认值 (8.4).[...] 类 X
的默认默认构造函数被定义为已删除,如果:
A default constructor for a class
X
is a constructor of classX
that can be called without an argument. If there is no user-declared constructor for classX
, a constructor having no parameters is implicitly declared as defaulted (8.4). [...] A defaulted default constructor for classX
is defined as deleted if:
[...]
X
是一个类似联合的类,它有一个带有非平凡默认构造函数的变体成员,
X
is a union-like class that has a variant member with a non-trivial default constructor,
[...]
- 任何直接或虚拟基类,或没有大括号或相等初始化器的非静态数据成员,具有类类型
M
(或其数组)和M
没有默认构造函数 或应用于M
的默认构造函数导致歧义或函数被删除或无法从默认的默认构造函数访问,或
- any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type
M
(or array thereof) and eitherM
has no default constructor or overload resolution (13.3) as applied toM
's default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or
[...]
您的类 A
没有默认构造函数,因此包含一个没有初始化程序的 A
类型的非静态数据成员会导致删除 X
的默认构造函数.它必须:编译器根本无法生成任何其他默认构造函数.
Your class A
has no default constructor, so a defaulted default constructor (whether implicit or explicit) for a class X
(whether union or non-union) containing a non-static data member of type A
without an initialiser leads to the default constructor for X
being deleted. It has to: there's simply no way for the compiler to generate any other default constructor.
至于您在评论中的后续问题:
As for your follow-up question in the comments:
如果不是 A
not 有一个默认构造函数,它有一个非平凡的默认构造函数,那么在联合中使用它和在联合中使用它是有区别的非联合类,这也是 [class.ctor]p5 的一部分:这是我在之前的引用中没有强调的第一个要点.
If instead of A
not having a default constructor, it has a non-trivial default constructor, then there is a difference between using that in a union and in a non-union class, and that is also part of [class.ctor]p5: it is the first bullet point that I included, without emphasis, in my earlier quote.
这篇关于如果联合中只有一个成员没有,为什么联合有一个已删除的默认构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如果联合中只有一个成员没有,为什么联合有一个已删除的默认构造函数?
基础教程推荐
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01