C ++ 11中的联合:默认构造函数似乎已删除 [英] Unions in C++11: default constructor seems to be deleted

查看:366
本文介绍了C ++ 11中的联合:默认构造函数似乎已删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解C ++ 11如何扩展联合.改变的一件事是现在可以将非静态数据成员与非平凡的特殊成员函数一起使用.来自 cppreference.com

I am trying to understand how unions were extended by C++11. One thing that changed is the ability to use now non-static data members with non-trivial special member functions. From cppreference.com

如果联合包含具有非平凡特殊成员函数的非静态数据成员(默认构造函数,复制/移动构造函数,复制/移动分配或析构函数),则默认情况下该函数在联合中被删除并需要由程序员明确定义. 最多一个数据成员可以具有一个默认的成员初始化程序.

If a union contains a non-static data member with a non-trivial special member function (default constructor, copy/move constructor, copy/move assignment, or destructor), that function is deleted by default in the union and needs to be defined explicitly by the programmer. At most one data member can have a default member initializer.

我正在尝试以下代码:

struct X
{
    ~X() {};
};

union U
{
    X x;
    ~U() {};
};

int main()
{
    U s1{};  // works, probably aggregate initialization
    U s2;    // DOES NOT compile, why?
}

在Coliru上直播

此处X(用作联合的数据成员)具有用户提供的析构函数,因此默认情况下会删除联合的析构函数.因此,我明确提供一个.但是,代码无法编译,并显示错误

Here X (which is used as a data member of the union) has a user provided destructor, hence the destructor of the union is by default deleted. Therefore I provide one explicitly. However, the code fails to compile, with the error

注意:"U :: U()"被隐式删除,因为默认定义格式不正确:

note: 'U::U()' is implicitly deleted because the default definition would be ill-formed:

如果我删除最后一行U s2;,则代码将编译.

The code compiles if I remove the last line U s2;.

问题?这是怎么回事?为什么U s1{};可以编译,而U s2;不能编译?联合的默认ctor是否标记为已删除(如果是,为什么?!),并且在第一种情况下,我们仅进行聚合初始化?请注意,如果我提供U(){}; // not U() = default;,则代码会编译(但如果我仅提供X的ctor,则不会编译).

Question What is going on here? Why U s1{}; compiles, but U s2; does not? Is the default ctor of the union marked as deleted (if so, why?!), and in the first case we have just aggregate initialization? Note that if I provide U(){}; // not U() = default; the code compiles (but not if I only provide a ctor of X).

编辑

深入研究标准(N4527):

After digging into the standard (N4527):

联盟:9.5/2 [class.union]

[注意:如果联合的任何非静态数据成员具有非平凡的默认构造函数(12.1),副本构造函数(12.8),移动构造函数(12.8),副本分配运算符(12.8),移动赋值运算符( 12.8)或析构函数(12.4),联合的相应成员函数必须由用户提供,否则将为联合隐式删除(8.4.3). —endnote]

[Note: 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. —endnote]

这似乎是gcc错误(现已在此处报道) ).该代码在clang和gcc 4.8.2或更早版本上编译,在gcc4.9和更高版本上中断(感谢@ T.C.指出).

it seems that this is a gcc bug (now reported here). The code compiles on clang and gcc 4.8.2 or earlier, it breaks on gcc4.9 and later (thanks @T.C. for pointing out).

编译器:使用g ++ 5.3,-std=c++11.

Compiler: g++5.3, -std=c++11 used.

推荐答案

X不是Pod类型,因为它具有析构函数,因此无法轻易复制 另外,U不是Pod类型.

X is not a pod type because is not trivially copiable as it have destructor Also U is not a pod type.

U s2; 尝试调用已删除的默认构造函数,以便出现错误

U s2; try to call the default costructor that is deleted so the error

U s1 {}; 使用明智的成员初始化,不要调用任何构造函数

U s1 {}; use member wise initialization and don't call any costructor

与非pod成员一起使用时,会删除默认的union构造函数,因为它将调用成员的默认构造函数,即编译器不知道哪个成员将调用默认的构造函数

In union with non pod member the default costructor of union is deleted because it would call the default costructor of members ie the compiler doesn't know which member to call the default costructor

 Union XX{
   string m1; 
   vector <int> m2;
}

XX的默认构造函数无法调用m1和m2的默认构造函数,因此将其删除

default costructor of XX cannot call default costructor of m1 AND m2 so it is deleted

这篇关于C ++ 11中的联合:默认构造函数似乎已删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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