我收集unrestricted unions
作为C ++ 11中提出的功能之一。任何人都可以解释这背后的语义及其提供的优势吗?
答案 0 :(得分:22)
维基百科上有一个解释:http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions
在询问C ++ 0x功能解释之前先搜索那里。
不受限制的工会
在标准C ++中 什么类型有限制 对象可以是联合的成员。 例如,工会不能包含任何 定义非平凡的对象 构造函数。 C ++ 0x将减轻一些 这些限制,允许工会 用于他们的更多类型 以前不允许使用 上。[6]这是一个简单的例子 在C ++ 0x中允许使用union:
//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. };
这些变化不会破坏任何变化 现有代码,因为他们只是放松 现行规则。
答案 1 :(得分:8)
这不过是我们一直拥有的旧工会,一个包含一个成员的对象,不同类型。
更改只是您现在可以在工会中存储非POD类型。但是,您将负责显式构造和销毁该成员。
来自N3242:
[示例:考虑具有非静态数据的联合类型U的对象u M类型的成员m和类型N的n。如果M有一个非平凡的析构函数,N有一个非平凡的构造函数 (例如,如果它们声明或继承虚函数),可以安全地切换u的活动成员 从m到n使用析构函数和放置new运算符如下:
u.m.〜M();
新的(&amp; u.n)N;
- 例子]
IMO并不是一个广泛有用的功能。
答案 2 :(得分:1)
它扩展了工会以允许任何类型,而不仅仅是简单的旧数据&#34;,使您可以更灵活地在同一位置存储不同类型的数据,而无需使用手动指针hackery。
您为此付出的代价是您必须谨慎记账。使用普通的旧数据联合分配足以改变&#34;当前类型&#34;并且阅读错误的类型可能会导致带标签的数据,但不会多于此。使用非普通旧数据uninion,您必须跟踪当前类型并手动调用corect构造函数和析构函数以更改当前类型并在销毁整个联合时正确清理。如果你试图读取或写入拧干类型,可能会发生坏事