C++11中提出了什么是无限制联合体?

19

我了解到C++11中提出了非限制性联合体(unrestricted unions)作为其功能之一。请问有人能够解释其语义以及其提供的优势吗?

3个回答

25

维基百科上有解释:http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions

在询问关于C++0x特性的解释之前,请先在那里搜索。

无限制联合体

在标准C++中,对于可以成为联合体成员的对象类型存在限制。例如,联合体不能包含定义了非平凡构造函数的任何对象。C++0x将减轻其中一些限制,允许联合体用于更多之前不被允许使用的类型[6]。以下是一个在C++0x中允许的简单联合体示例:

//for placement new
#include <new>

struct Point  {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};
union U {
    int z;
    double w;
    Point p;  // Illegal in C++; point has a non-trivial constructor. 
              //   However, this is legal in C++0x.
    U() { new( &p ) Point(); } // No nontrivial member functions are
                               //implicitly defined for a union;
                               // if required they are instead deleted
                               // to force a manual definition.
};

这些更改不会破坏任何现有的代码,因为它们仅仅放宽了当前的规则。


9
这只是我们一直拥有的旧联合体,每次只包含一个成员,类型各不相同。
改变的只是现在允许在联合体中存储非POD类型。但是,您将需要负责显式构造和销毁该成员。
来自N3242:
例如:考虑具有类型M和N的非静态数据成员m和n的联合类型U的对象u。如果M具有非平凡的析构函数并且N具有非平凡的构造函数(例如,如果它们声明或继承虚函数),则可以使用析构函数和放置new运算符安全地从m切换到n的活动成员,如下所示:
u.m.~M();
new (&u.n) N;
-示例结束]
在我看来,这并不是一个广泛有用的功能。

1
它扩展了联合以允许任何类型,而不仅仅是“普通数据”,从而为您提供更多灵活性,使您能够在同一位置存储不同类型的数据,而无需采用手动指针技巧。
这样做的代价是需要进行一些仔细的簿记。对于普通数据联合,分配足以改变“当前类型”,读取错误类型可能会导致混乱的数据,但不会有更多的影响。使用非普通数据联合,您必须跟踪当前类型并手动调用正确的构造函数和析构函数来更改当前类型,并在销毁整个联合时正确清理事物。如果尝试读取或写入错误类型,则可能会发生糟糕的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接