c – 为什么联盟已经删除默认构造函数,如果其中一个成员没有任何一个?

N3797 :: 9.5 / 2 [class.union]说:

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

我试图通过例子来理解这个说明:

#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()
{

}

DEMO

这种行为对我来说不是很清楚. struct A没有隐式声明的认构造函数,因为12.1 / 4:[class.ctor]说:

If there is no user-declared constructor for class X,a constructor
having no parameters is implicitly declared as defaulted (8.4).

这意味着struct A没有一个非平凡的认构造函数(根本没有认构造函数,特别是非平凡的).这是联合U不必具有删除认构造函数.怎么了?

解决方法

相关措辞在C 11 [class.ctor] p5(强调我的):

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X,a constructor having no parameters is implicitly declared as defaulted (8.4). […] A defaulted default constructor for class X is defined as deleted if:

[…]

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

[…]

  • 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 either M has no default constructor or overload resolution (13.3) as applied to M‘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(无论是联合还是非联合)都不使用初始化,导致认构造函数X被删除.它必须:编译器根本没有办法生成任何其他认构造函数.

至于您在评论中的后续问题:

如果代替A没有认构造函数,它有一个非平凡的认构造函数,那么在一个union和一个非union类中使用它们之间有区别,也是[class.ctor] p5的一部分:这是我之前引用的第一个重点,我没有重点介绍.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...