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(无论是union还是非union)的默认默认构造函数(无论是隐式还是显式)导致默认构造函数为X被删除.它必须:编译器根本无法生成任何其他默认构造函数.

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

如果没有A没有默认构造函数,它有一个非平凡的默认构造函数,那么在union和non-union类中使用它有区别,这也是[class.ctor] p5的一部分:这是我在前面的引文中没有强调的第一个要点.

上一篇:图的关键路径,AOE,完整实现,C++描述


下一篇:js获取url参数、图片转本地base64跨域问题