I gather unrestricted unions
as one of the functionality being put forth in C++11. Can anyone please explain the semantics behind this and the advantages it provides?
The unrestricted unions of C++11 can have data members that are not plain-old-data (POD) type . Typically unions are used in a struct with an enum to store the data and its type. We have an example code below that defines an anonymous unrestricted union of 2 non-POD types (Tiger and Lion).
Purpose of Unions in C/ C++ Union is a user-defined datatype. All the members of union share same memory location. Size of union is decided by the size of largest member of union. If you want to use same memory location for two or more members, union is the best for that.
A union can have member functions (including constructors and destructors), but not virtual functions. A union cannot have base classes and cannot be used as a base class.
There is an explaination on Wikipedia : http://en.wikipedia.org/wiki/C%2B%2B0x#Unrestricted_unions
Search there first before asking about C++0x features explainations.
Unrestricted unions
In Standard C++ there are restrictions on what types of objects can be members of a union. For example, unions cannot contain any objects that define a non-trivial constructor. C++0x will alleviate some of these restrictions, allowing unions to be used on more types that they were previously not allowed to be used on.[6] This is a simple example of a union permitted in 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. };
The changes will not break any existing code since they only relax current rules.
It is nothing else than the old unions we have always had, an object containing one member at a time, of varying type.
The change is just that you are now allowed to store non-POD types in a union. However, you will then be responsible for explicitly constructing and destroying that member.
From N3242:
[ Example: Consider an object u of a union type U having non-static data members m of type M and n of type N. If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new operator as follows:
u.m.~M();
new (&u.n) N;
—end example ]
Not a widely useful feature, IMO.
It expands unions to allow any type, not just "plain old data", giving you more flexibility to store different types of data in the same location without resorting to manual pointer hackery.
The price you pay for this is that you have to do some careful book keeping. With a plain old data union assignment was enough to change the "current type" and reading the wrong type was likely to result in garbled data but not much more than that. With a non plain old data union you must keep track of the current type and call the correct constructors and destructors manually to change the current type and to clean things up correctly when destroying the union as a whole. If you try to read or write the wring type bad things are likely to happen
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With