Reputation: 5204
I was trying to learn more about unions and their usefulness, when I was surprised that the following code is perfectly valid and works exactly as expected:
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;
}
Until now, I had no idea that it is legal to declare unions with templates, constructors, destructor, and even member functions. In case it's relevant, I'm using Visual Studio 2012.
When I searched the internet to find more about using unions in this manner, I found nothing. Is this a new feature of C++, or something specific to MSVC? If not, I'd like to learn more about unions, specifically examples of them used like classes (above). If someone could point me to a more detailed explanation of unions and their usage as data structures, it'd be much appreciated.
Upvotes: 4
Views: 328
Reputation: 158629
Is this a new feature of C++, or something specific to MSVC?
No, as BoBtFish said, the 2003 C++ standard section 9.5 Unions
paragraph 1
says:
[...] A union can have member functions (including constructors and destructors), but not virtual (10.3) functions. A union shall not have base classes. A union shall not be used as a base class. An object of a class with a non-trivial constructor (12.1), a non-trivial copy constructor (12.8), a non-trivial destructor (12.4), or a non-trivial copy assignment operator (13.5.3, 12.8) cannot be a member of a union, nor can an array of such objects. If a union contains a static data member, or a member of reference type, the program is ill-formed.
union
s do come under section 9 Classes
and the grammar for class-key is as follows:
class-key:
class
struct
union
So acts like a class
but has many more restrictions. The key restriction being that unions
can only have one active non-static member at a time, which is also covered in paragraph 1
:
In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time. [...]
The wording in the C++11 draft standard
is similar so it has not changed too much since 2003
.
As for the use of a union
, there are two common reasons which are covered from different angles in this previous thread C/C++: When would anyone use a union? Is it basically a remnant from the C only days? to summarize:
To implement your own Variant type
, a union
gives you the ability to represent all the varying types without wasting memory. This answer to the thread gives a good example.
Type punning
but I would read Understanding Strict Aliasing
as well since there are many cases where type punning
is undefined behavior.
This answer to Unions cannot be used as Base class
gives some really great insight into why unions
are implemented as they are in C++
.
Upvotes: 2