Enums, Structs and Unions
Three ways to build your own data types
int, double, bool) are rarely enough to model a real problem. C++ lets you design your own types. An enum names a fixed set of related values, a struct groups several fields into one bundle, and a union lets several fields share the same memory. Knowing which one fits is a core intermediate skill.
- declare a scoped
enum classand control its underlying type, - define a
structwith fields, default initializers and member functions, - understand what a
unionis and why it is dangerous without a tag, - reach for the right tool - and know when
std::variantreplaces a raw union.
1. Enums: a name for each valid value
Imagine a traffic light. It is never "7" or "-3" - it is only Red, Yellow or Green. An enumeration (enum) is a type whose values you list by name, so the compiler can guarantee only those names are used.
Modern C++ prefers the scoped enum, written enum class. Its names live inside the enum's own scope and it does not silently convert to int.
enum class Color { Red, Yellow, Green };
Color c = Color::Green; // must qualify with Color::
// int n = c; // ERROR: no implicit conversion
int n = static_cast<int>(c); // OK: explicit, n == 2
By default the first name is 0, the next 1, and so on. You can set values yourself, and you can choose the underlying type (the integer type used to store it):
enum class Status : unsigned char {
Ok = 0,
Warning = 10,
Error = 20
};
The old style, plain enum Color { Red, Green };, dumps Red and Green straight into the surrounding scope and converts to int on its own. That looseness causes name clashes and silent bugs, which is exactly why enum class was added in C++11.
enum class by default. Use a plain enum only for old-style bit flags where the automatic int conversion is genuinely convenient.