为什么union已经删除默认构造函数,如果其成员之一没有一个? [英] Why does union has deleted default constructor if one of its member doesn't have one whatsoever?

查看:2244
本文介绍了为什么union已经删除默认构造函数,如果其成员之一没有一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


如果联合的任何非静态数据成员具有非平凡默认
构造函数(12.1),复制构造函数(12.8),移动构造函数(12.8),
赋值运算符(12.8),移动赋值运算符(12.8)或
析构函数(12.4),联合的相应成员函数
必须是用户提供的或者将被隐式删除(8.4.3)对于
联合


我试图通过示例理解该笔记:

  #include< iostream> 
#include< limits>

struct A
{
A(const A&){std :: cout< 〜A()< std :: endl; } // A没有默认构造函数
};

union U
{
A a;
};

U u; //错误:调用隐式删除的默认构造函数'U'

int main()
{

}

DEMO



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


如果类X没有用户声明的构造函数,那么没有参数的构造函数
会隐式声明为默认)。


这意味着 struct A 没有非平凡默认构造函数(根本没有默认构造函数,特别是非平凡的)。 union U 不必具有已删除的默认构造函数。

解决方案

相关的措辞在C ++ 11 [class.ctor] p5 p>


X 默认构造函数是一个构造函数的 X 可以在没有参数的情况下调用。如果没有用户声明的类 X 的构造函数,那么没有参数的构造函数将被隐式声明为默认值(8.4)。 [...] X 的默认默认构造函数定义为删除,如果:



[...]




  • X 具有不重要的默认构造函数的变量成员



[...]




  • 任何直接或虚拟基类或非静态数据成员,不带大括号或等于初始值 ,类类型 M (或其数组),并且 M 默认构造函数或重载分辨率(13.3)应用于 M 的默认构造函数会导致模糊性,或在函数中被删除或无法从默认默认构造函数或



[...]



$ b b

您的类 A 没有默认构造函数,因此默认的默认构造函数(无论是隐式的还是显式的) X A (不带初始化器)的非静态数据成员的$ c>(无论是联合还是非联合)导致 X的默认构造函数正在删除。它必须:编译器根本没有办法生成任何其他默认构造函数。



对于你的后续问题在注释中:



如果不是 A 没有一个默认的构造函数,它有一个非平凡的默认构造函数,那么是在联合和非联合类中使用的区别,也是[class.ctor] p5的一部分:这是我在之前的引用中包含的第一个重点, p>

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

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

}

DEMO

That behavior isn't quite clear to me. struct A doesn't have implicitly-declared default constructor, because 12.1/4: [class.ctor] says:

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

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?

解决方案

The relevant wording is in C++11 [class.ctor]p5 (emphasis mine):

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

[...]

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:

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.

这篇关于为什么union已经删除默认构造函数,如果其成员之一没有一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆