Unions are rarely used but are another important data type alternative to structs and classes in modern C++ development. Unions are used to define variables that share storage space. The C++11 standard loosens up the restriction regarding members of unions, and in this post, we explain the unrestricted unions feature that came with C++11.
Table of Contents
What is a union in modern C++?
Unions are used to define variables that share storage space. It is a special data type that can store only one of its non-static data members at a time. The compiler allocates enough storage in a number to accommodate the largest element in the union. Unlike a struct, the members of a union occupy the same location in memory. Writing into one overwrites all others.
Since C++11, here is the general syntax for the union:
1 2 3 |
union attr union_name { member_specifications } |
We can use the record selector .
to access elements of a union as in structs and classes.
How to use a union declaration in modern C++?
The general declaration syntax for unions is similar to that for structures. The differences are:
- Unions can contain bit fields, but only one can be active. They all start at the beginning of the union. (Note that, because bit fields are machine dependent, they can pose problems when writing portable code.)
- Unlike C++ structures, C++ union types cannot use the class access specifiers: public, private, and protected. All fields of a union are public.
- Unions can be initialized only through their first declared member:
Here is a simple union declaration and definition,
1 2 3 4 5 6 7 |
union u { int i; double d; }; |
A union can’t participate in a class hierarchy. It can’t be derived from any class, nor can it be a base class. A union can have a constructor.
What is the unrestricted unions feature in modern C++?
Starting with C++11, some of the restrictions mentioned above have been disabled. Since C++11, unions are able to contain objects that have a non-trivial constructor. If a union contains such an object, the implicit default constructor of the union is deleted, forcing the user to manually define a constructor.
Here is a simple example, let’s assume we have a special struct to store x, y, z coordinates:
1 2 3 4 5 6 7 8 |
struct T3DPoint { T3DPoint() {} T3DPoint(int x, int y, int z): x_(x), y_(y), z_(z) {} int x_, y_, z_; }; |
C++11 allows us to use these kinds of classes and and their objects. Here is an example to unrestricted unions that uses the struct we define above,
1 2 3 4 5 6 7 8 |
union U { double w; T3DPoint p; // Allowed in C++11. U() { new(&p) T3DPoint(); } // Due to the 3DPoint member, a user-defined constructor is now required. }; |
Is there a full example of unrestricted unions in modern C++?
Here is the full example of how to use unrestricted unions in C++.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <iostream> struct T3DPoint { T3DPoint() {} T3DPoint(int x, int y, int z): x_(x), y_(y), z_(z) {} int x_, y_, z_; }; union U { double w; T3DPoint p; // Allowed in C++11. U() { new(&p) T3DPoint(); } // Due to the 3DPoint member, a user-defined constructor is now required. }; int main() { } |
For more information on this feature, check this link and see Unrestricted unions Proposal document.
C++ Builder is the easiest and fastest C and C++ IDE for building simple or professional applications on the Windows, MacOS, iOS & Android operating systems. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for cross-platform UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise version.