Enum
In C++, an enumeration (enum) is a user defined type where a set of values is specified for a variable and the variable can only take one out of a small set of possible values.
Syntax
The keyword enum
is used to define an enumeration.
enum name {const1, const2, ...};
Here’s an example:
enum day {sun, mon, tue, wed, thu, fri, sat};
sun
would have the value 0mon
would have the value 1tue
would have the value 2wed
would have the value 3thu
would have the value 4fri
would have the value 5sat
would have the value 6
Here’s another example where one of the constants is assigned a value:
enum grade {freshman=9, sophomore, junior, senior};
The enumerator freshman
is assigned the value 9
. Subsequent enumerators, if they are not given an explicit value, receive the value of the previous enumerator plus one.
So here:
freshman
would have the value 9sophomore
would have the value 10junior
would have the value 11senior
would have the value 12
Codebyte Example
Scoped Enums
Scoped enums are a feature added in C++11.
Scoped enums differ from unscoped enums by:
- Containing their constants in their namespace.
- Being strongly-typed.
- By containing their constants to their namespace, scoped enumerations avoid name conflicts with other enumerations.
Example
enum class WeekDay {sun, mon, tue, wed, thu, fri, sat};WeekDay day = WeekDay::sun; // Notice that "sun" is prefaced with "Weekday::"int friday = WeekDay::fri; // error, must cast to an int
Here’s an example where scoped enumerations avoid name collisions:
enum class LogResult {Success, InvalidFileName, WriteError};enum class SocketResult {Success, InvalidAddrError, TimeoutError};LogResult logger_result = LogResult::Success;if (logger_result == LogResult::Success) {} // Because Success is scoped to LogResult, it doesn't collide with SocketResult::Success
Enum to Int Conversion
In C++, enum
can be implicitly converted to integers, useful for numeric contexts like array indexing or bitwise operations:
#include <iostream>enum color { red, green, blue };int main() {color c = green;int colorValue = c; // Implicit conversion to intstd::cout << "Color value: " << colorValue;}
Here is the output:
Color value: 1
Converting an enum
to int
is easy, but converting int
to enum
is risky as no bounds check is done, leading to undefined behavior if the value is out of range.
Custom Underlying Types
By default, an enum’s type is int
, but a smaller type like unsigned char
can be specified to optimize memory usage:
#include <iostream>enum class Permission : unsigned char {Read = 1,Write = 2,Execute = 4};int main() {Permission p = Permission::Write;std::cout << static_cast<int>(p); // Explicit cast to int}
Here, the underlying type of Permission
is unsigned char
. The constants Read
, Write
, and Execute
are stored using only 1 byte of memory.
This example results in the following output:
2
Best Practices
Here are some best practices for using enums:
- Use
enum class
for strong typing: Scoped enums (C++11) prevent implicit int conversions, ensuring better type safety. - Explicit casting: Use
static_cast<int>(enum_value)
for safe conversions. - Avoid magic numbers: Enums replace hardcoded numbers, improving readability.
- Use underlying types wisely: Choose the underlying type carefully in memory-constrained environments.
All contributors
- Anonymous contributor
- Anonymous contributor
- yekyam
- Arinze_Obi
- Prince25
- Christine_Yang
- garanews
- christian.dinh
Contribute to Docs
- Learn more about how to get involved.
- Edit this page on GitHub to fix an error or make an improvement.
- Submit feedback to let us know how we can improve Docs.
Learn C++ on Codecademy
- Career path
Computer Science
Looking for an introduction to the theory behind programming? Master Python while learning data structures, algorithms, and more!Includes 6 CoursesWith Professional CertificationBeginner Friendly75 hours - Free course
Learn C++
Learn C++ — a versatile programming language that’s important for developing software, games, databases, and more.Beginner Friendly11 hours