An enumeration, commonly called an enum, is a user-defined type that consists of a set of named values. Enums are useful when a variable should contain one value from a small, predefined set of choices.
An enumeration is a user-defined type containing a collection of named constants.
For example, days of a week can be represented using:
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
Each name represents a possible value of the Day type.
The basic syntax of an enum is:
enum EnumName {
value1,
value2,
value3
};
The enum definition ends with a semicolon.
enum Color {
Red,
Green,
Blue
};
Here, Color is an enumeration and
Red, Green, and Blue are its
named values.
After defining an enum, we can create a variable of that enum type.
enum Color {
Red,
Green,
Blue
};
Color color = Green;
Here, color stores the enum value Green.
By default, the first enumerator has the value 0, and
the following values normally increase by one.
enum Color {
Red,
Green,
Blue
};
The underlying numeric values are commonly:
Red = 0
Green = 1
Blue = 2
We can explicitly assign values to enumerators.
enum Level {
Low = 1,
Medium = 5,
High = 10
};
Here, the values are explicitly specified instead of using the default sequence.
If one enumerator has an explicit value, the following enumerators continue from that value unless another value is specified.
enum Number {
One = 1,
Two,
Three,
Four
};
The values are:
One = 1
Two = 2
Three = 3
Four = 4
Enums work very well with switch statements.
enum Day {
Monday,
Tuesday,
Wednesday
};
Day today = Tuesday;
switch (today) {
case Monday:
std::cout << "Monday";
break;
case Tuesday:
std::cout << "Tuesday";
break;
case Wednesday:
std::cout << "Wednesday";
break;
}
enum TrafficLight {
Red,
Yellow,
Green
};
TrafficLight light = Green;
if (light == Green) {
std::cout << "Go";
}
Enum values can be compared using comparison operators.
Traditional unscoped enum values can be converted to an integer context.
enum Color {
Red,
Green,
Blue
};
Color color = Green;
std::cout << color;
With the default values, Green corresponds to
1.
An enum value can be explicitly converted to an integer.
enum Color {
Red = 1,
Green = 2,
Blue = 3
};
Color color = Blue;
int value = static_cast<int>(color);
std::cout << value;
Output:
3
C++ also provides enum class, which is a scoped enumeration.
enum class Color {
Red,
Green,
Blue
};
Enum classes provide stronger type safety and keep their enumerator names scoped inside the enum.
enum class Color {
Red,
Green,
Blue
};
Color color = Color::Green;
The scope operator :: is used to access the enumerators.
The following form is used instead of simply writing
Green:
Color::Green
| enum | enum class |
|---|---|
| Unscoped by default. | Scoped. |
| Enumerator names can be visible in the surrounding scope. | Enumerator names remain inside the enum's scope. |
| Can implicitly convert to integer in appropriate contexts. | Does not implicitly convert to integer. |
| Provides less type safety. | Provides stronger type safety. |
enum class Day {
Monday,
Tuesday,
Wednesday
};
Day today = Day::Tuesday;
switch (today) {
case Day::Monday:
std::cout << "Monday";
break;
case Day::Tuesday:
std::cout << "Tuesday";
break;
case Day::Wednesday:
std::cout << "Wednesday";
break;
}
enum class Status {
Pending = 1,
Approved = 2,
Rejected = 3
};
Custom values can also be assigned to an enum class.
Status status = Status::Approved;
An enumeration has an underlying integral type used to represent its values. The compiler can choose a suitable underlying type unless one is explicitly specified.
For example:
enum class Status : int {
Pending = 1,
Approved = 2,
Rejected = 3
};
Here, int is explicitly specified as the underlying type.
enum class Level {
Low,
Medium,
High
};
void displayLevel(Level level) {
if (level == Level::High) {
std::cout << "High Level";
}
}
int main() {
displayLevel(Level::High);
return 0;
}
Enum values can be passed to functions just like other typed values.
enum class Result {
Pass,
Fail
};
Result checkMarks(int marks) {
if (marks >= 40) {
return Result::Pass;
}
return Result::Fail;
}
int main() {
Result result = checkMarks(75);
if (result == Result::Pass) {
std::cout << "Student Passed";
}
return 0;
}
enum class Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
Day today = Day::Friday;
An enum is useful when a variable should contain one value from a fixed collection.
enum class TrafficLight {
Red,
Yellow,
Green
};
TrafficLight light = TrafficLight::Red;
if (light == TrafficLight::Red) {
std::cout << "Stop";
}
This makes the program more readable than using unexplained numbers.
enum class Result {
Fail,
Pass
};
Result result = Result::Pass;
if (result == Result::Pass) {
std::cout << "Congratulations!";
}
Enums are useful when only a small number of predefined states are valid.
enum class Role {
Admin,
Teacher,
Student
};
Role userRole = Role::Teacher;
if (userRole == Role::Teacher) {
std::cout << "Teacher Access";
}
This approach can make role-based program logic easier to understand.
An enum can be used with an array when enum values represent fixed positions.
enum class Day {
Monday,
Tuesday,
Wednesday
};
std::string names[3] = {
"Monday",
"Tuesday",
"Wednesday"
};
Day today = Day::Tuesday;
std::cout <<
names[static_cast<int>(today)];
The explicit conversion is required because an enum class does not implicitly convert to an integer.
enum class Level {
Low,
Medium,
High
};
Level current = Level::High;
if (current == Level::High) {
std::cout << "High";
}
if (current != Level::Low) {
std::cout << "Not Low";
}
Values from the same enum type can be compared.
#include <iostream>
enum class Menu {
Home = 1,
Courses = 2,
Contact = 3,
Exit = 4
};
int main() {
Menu choice = Menu::Courses;
switch (choice) {
case Menu::Home:
std::cout << "Home";
break;
case Menu::Courses:
std::cout << "Courses";
break;
case Menu::Contact:
std::cout << "Contact";
break;
case Menu::Exit:
std::cout << "Exit";
break;
}
return 0;
}
static_cast<int> when an explicit integer conversion is required.switch when different actions are required for different enum values.| Concept | Meaning |
|---|---|
| enum | A user-defined type containing named values. |
| Enumerator | A named value inside an enumeration. |
| Default Value | The first unassigned enumerator normally starts at 0. |
| Custom Value | An enumerator can be assigned a specific integral value. |
| enum class | A scoped enumeration with stronger type safety. |
| static_cast | Can be used for explicit conversion between enum values and compatible integer values. |
| switch | Commonly used to perform different actions for different enum values. |
enum class Status {
Pending,
Approved,
Rejected
};
Status status = Status::Approved;
if (status == Status::Approved) {
std::cout << "Approved";
}
enum class provides scoped names and stronger type safety.::.switch statements.Question: Which feature provides scoped enumerator names and stronger type safety in C++?