当我惊讶地发现以下代码完全有效并且完全符合预期时,我试图更多地了解工会及其实用性:
template <class T>
union Foo
{
T a;
float b;
Foo(const T& value)
: a(value)
{
}
Foo(float f)
: b(f)
{
}
void bar()
{
}
~Foo()
{
}
};
int main(int argc, char* argv[])
{
Foo<int> foo1(12.0f);
Foo<int> foo2((int) 12);
foo1.bar();
foo2.bar();
int s = sizeof(foo1); // s = 4, correct
return 0;
}
到目前为止,我不知道使用模板,构造函数,析构函数甚至成员函数声明联合是合法的。如果它是相关的,我正在使用Visual Studio 2012。
当我在互联网上搜索更多关于以这种方式使用工会时,我一无所获。这是C ++的新功能,还是MSVC特有的功能?如果没有,我想了解更多关于工会的信息,特别是类似于类的例子(上图)。如果有人能够指出我对工会及其作为数据结构的使用的更详细解释,我们将不胜感激。
答案 0 :(得分:2)
这是C ++的新功能,还是MSVC特有的功能?
不,正如BoBtFish所说,2003 C ++标准部分9.5 Unions
段1
说:
[...] union 可以包含成员函数(包括构造函数和析构函数),但不能包含虚函数(10.3)。工会不得有基类。联合不得用作基类。具有非平凡构造函数(12.1),非平凡复制构造函数(12.8),非平凡析构函数(12.4)或非平凡复制赋值运算符(13.5.3,12.8)的类的对象不能是一个联盟的成员,也不是一系列这样的对象。如果联合包含静态数据成员或引用类型的成员,则该程序格式不正确。
union
确实属于9 Classes
部分,而class-key的语法如下:
class-key:
class
struct
union
所以行为就像class
,但有更多限制。关键限制是unions
一次只能有一个活跃的非静态成员,这也在第1
段中有所涵盖:
在联合中,最多一个非静态数据成员可以随时处于活动状态,也就是说,最多可以存储一个非静态数据成员的值在任何时候的工会。 [...]
C++11 draft standard
中的措辞相似,因此自2003
以来没有太大变化。
关于union
的使用,有两个常见的原因可以从前一个帖子C/C++: When would anyone use a union? Is it basically a remnant from the C only days?中的不同角度进行总结:
要实现自己的Variant type
,union
使您能够代表所有不同的类型,而不会浪费内存。该帖子的This answer给出了一个很好的例子。
Type punning
但我也会阅读Understanding Strict Aliasing
,因为很多情况下type punning
是undefined behavior。
此answer到Unions cannot be used as Base class
可以很好地了解为unions
实施C++
的原因。