Enumerations in C++
An enumeration (also called enum) is a way to create a set of named integer constants. Instead of using plain numbers like 0, 1, 2, 3 in your code — which are hard to read — you give each number a meaningful name. Think of it like labeling the buttons on a TV remote: instead of pressing button number 2, you press the button labeled Volume Up.
Enums make code cleaner, more readable, and less error-prone. They are widely used to represent states, categories, directions, days of the week, and similar fixed sets of values.
Why Use Enumerations?
Imagine writing a program that handles traffic lights. Without enums:
int light = 0; // 0 = RED, 1 = YELLOW, 2 = GREEN
A reader cannot tell what 0, 1, or 2 means without reading the comment. With enums:
enum Light { RED, YELLOW, GREEN };
Light current = RED;
Now the code is self-explanatory. RED means red — no comment needed.
Declaring an Enum
enum EnumName {
VALUE1,
VALUE2,
VALUE3
};
By default, VALUE1 starts at 0, VALUE2 is 1, and so on. Each constant automatically gets the next integer value.
Basic Enum Example
#include <iostream>
using namespace std;
enum Day {
MONDAY, // 0
TUESDAY, // 1
WEDNESDAY, // 2
THURSDAY, // 3
FRIDAY, // 4
SATURDAY, // 5
SUNDAY // 6
};
int main() {
Day today = WEDNESDAY;
cout << "Day number: " << today << endl;
if (today == WEDNESDAY) {
cout << "It's the middle of the week!" << endl;
}
return 0;
}
Output:
Day number: 2
It's the middle of the week!
Custom Values in Enums
You can assign specific integer values to enum constants. Constants after an assigned one continue incrementing from there.
#include <iostream>
using namespace std;
enum StatusCode {
OK = 200,
NOT_FOUND = 404,
ERROR = 500
};
int main() {
StatusCode response = NOT_FOUND;
cout << "Response code: " << response << endl;
return 0;
}
Output:
Response code: 404
Partial Assignment Example
enum Priority {
LOW = 1,
MEDIUM, // automatically becomes 2
HIGH, // automatically becomes 3
CRITICAL = 10
};
Using Enum in a Switch Statement
Enums work very well with switch statements because each case maps to a readable name instead of a plain number.
#include <iostream>
using namespace std;
enum Season { SPRING, SUMMER, AUTUMN, WINTER };
int main() {
Season now = SUMMER;
switch (now) {
case SPRING: cout << "Flowers bloom." << endl; break;
case SUMMER: cout << "It's hot outside." << endl; break;
case AUTUMN: cout << "Leaves are falling." << endl; break;
case WINTER: cout << "It's cold and snowy." << endl; break;
}
return 0;
}
Output:
It's hot outside.
Enum Class (Scoped Enum) — C++11
The older plain enum has a problem: its values leak into the surrounding scope. Two enums can accidentally share the same name, causing conflicts. C++11 introduced enum class (also called scoped enum) to fix this.
Problem with Plain Enum
enum Color { RED, GREEN, BLUE };
enum Fruit { APPLE, GREEN, MANGO }; // ERROR: GREEN already defined
Solution: enum class
#include <iostream>
using namespace std;
enum class Color { RED, GREEN, BLUE };
enum class Fruit { APPLE, GREEN, MANGO }; // no conflict now
int main() {
Color c = Color::GREEN;
Fruit f = Fruit::GREEN;
if (c == Color::GREEN) {
cout << "Color is green." << endl;
}
if (f == Fruit::GREEN) {
cout << "Fruit is green (could be lime!)." << endl;
}
return 0;
}
Output:
Color is green.
Fruit is green (could be lime!).
With enum class, you must prefix each value with the enum name using ::. This prevents name collisions and makes code much clearer in large programs.
Diagram: Plain Enum vs Enum Class
Plain enum:
┌──────────────────────────────────────┐
│ enum Direction { UP, DOWN, LEFT } │
│ Access: UP (no prefix needed) │
│ Risk: name clashes with other enums │
└──────────────────────────────────────┘
Scoped enum class:
┌──────────────────────────────────────────────┐
│ enum class Direction { UP, DOWN, LEFT } │
│ Access: Direction::UP (prefix required) │
│ Safe: names stay inside enum scope │
└──────────────────────────────────────────────┘
Changing the Underlying Type of Enum Class
By default, enum class values are stored as int. You can specify a different underlying type to save memory or match a specific data format.
enum class Direction : char {
NORTH = 'N',
SOUTH = 'S',
EAST = 'E',
WEST = 'W'
};
Converting Enum to Integer
A plain enum converts to int automatically. An enum class requires an explicit cast.
#include <iostream>
using namespace std;
enum class Level { BEGINNER, INTERMEDIATE, ADVANCED };
int main() {
Level l = Level::ADVANCED;
int val = static_cast<int>(l);
cout << "Level value: " << val << endl; // 2
return 0;
}
Output:
Level value: 2
Real-World Enum Example: Game Character States
#include <iostream>
using namespace std;
enum class PlayerState {
IDLE,
RUNNING,
JUMPING,
ATTACKING,
DEAD
};
void printState(PlayerState state) {
switch (state) {
case PlayerState::IDLE: cout << "Player is standing still." << endl; break;
case PlayerState::RUNNING: cout << "Player is running." << endl; break;
case PlayerState::JUMPING: cout << "Player jumps into the air!" << endl; break;
case PlayerState::ATTACKING: cout << "Player attacks the enemy." << endl; break;
case PlayerState::DEAD: cout << "Game Over." << endl; break;
}
}
int main() {
PlayerState current = PlayerState::JUMPING;
printState(current);
return 0;
}
Output:
Player jumps into the air!
Comparison: Plain Enum vs Enum Class
| Feature | enum | enum class |
|---|---|---|
| Scope | Global (leaks into outer scope) | Scoped (stays inside enum) |
| Name conflict risk | High | None |
| Implicit int conversion | Yes | No (needs static_cast) |
| Access style | VALUE | EnumName::VALUE |
| Recommended for new code | No | Yes |
Key Takeaways
- Enums let you define a set of named integer constants for cleaner code.
- By default, enum values start at 0 and increment by 1.
- You can assign custom integer values to any enum constant.
- Enums pair naturally with
switchstatements for readable branching. - Prefer
enum classover plainenumin modern C++ to avoid name collisions. enum classvalues need an explicit cast to convert toint.
