2.1 The Plain enum
2.1.1 Defining an Enum
The syntax for defining an enum in C++ is similar to Rust. In addition, like in Rust, enum
variants are represented as integers at the low level, and by default the value starts from 0.
enum LogLevel
{
Debug, // 0
Info, // 1
Warning, // 2
Error // 3
};You can also manually assign values to the variants (also valid in Rust):
enum LogLevel
{
Debug = 0x12,
Info = 0xd1,
Warning = 0x7c,
Error = 0x0a,
};Unlike Rust, C++ by default uses the int type to represent the variants, even though most of the
time the number of variants won’t exceed 256. To use a more compact representation, you can do:
enum MyEnum : uint8_t
// or `enum Foo : char` (remember that `char` is an integer type)
{
Foo,
Bar,
};2.1.2 Using an Enum
Unlike Rust, a C++ enum does not create a namespace, which means you cannot write LogLevel::Info
to refer to the Info variant of the LogLevel enum defined in the prevous subsection. You should
write Info directly.
A enum is implicitly converted to an integer. Which means it can be directly compared to an integer
(but dont’t actually do this) and can be pushed to std::cout directly.
LogLevel lvl = Info;
assert(Info == 1);
assert(Warning > 1);
assert(Error > Debug);
std::cout << lvl << std::endl;However, an integer cannot be converted implicitly into an enum, but can be done so explicitly:
LogLevel lvl = 2; // won't work
LogLevel lvl = (LogLevel)2; // OK, but don't actually do thisYou can reassign the identifier Info to another value
int Info = 999;…but can you set another LogLevel to Info?
LogLevel m = Info; // Error!No you can’t. C++ generally forbids re-defining variables, but in the case of
enums you are allowed to re-bind a enum variant identifier (Info) to another
value (999), then you just can’t use that enum variant.
To avoid this and other kinds of conflicts, it had been a common practice to
enum variants with part of the enum name. For example, the LogLevel enum
may be rewritten as:
enum LogLevel
{
LevelDebug,
LevelInfo,
LevelWarning,
LevelError
};…which violates the DRY rule in a bad way. To solve this problem, enum class was introduced
in C++11, and we’ll learn about it in the next section.