Skip to content

[Edit] C++: enum #7296

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 187 additions & 92 deletions content/cpp/concepts/enum/enum.md
Original file line number Diff line number Diff line change
@@ -1,162 +1,257 @@
---
Title: 'Enum'
Description: 'Defines a variable with a limited set of predefined values.'
Title: 'enum'
Description: 'Defines a set of named integer constants in C++ for better code readability and maintainability.'
Subjects:
- 'Code Foundations'
- 'Computer Science'
- 'Game Development'
Tags:
- 'Enum'
- 'Data Types'
- 'Arrays'
- 'Vectors'
- 'Pointers'
- 'Memory'
- 'Enum'
- 'Variables'
CatalogContent:
- 'learn-c-plus-plus'
- 'paths/computer-science'
---

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.
An **`enum`** is a user-defined [data type](https://www.codecademy.com/resources/docs/cpp/data-types) in C++ that defines a set of named integer constants. It provides a way to create symbolic names for a group of related values, making code more readable and maintainable. Enums are particularly useful when you need to represent a fixed set of options or states in your program.

## Syntax
Enums are commonly used in scenarios such as representing days of the week, menu options, game states, error codes, or any situation where you have a limited set of predefined values. They help prevent magic numbers in code and make programs more self-documenting.

The keyword `enum` is used to define an enumeration.
## Syntax

```cpp
enum name {const1, const2, ...};
```pseudo
enum enum_name {
constant1,
constant2,
constant3,
...
};
```

Here's an example:
**Parameters:**

```cpp
enum day {sun, mon, tue, wed, thu, fri, sat};
```

- `sun` would have the value 0
- `mon` would have the value 1
- `tue` would have the value 2
- `wed` would have the value 3
- `thu` would have the value 4
- `fri` would have the value 5
- `sat` would have the value 6
- `enum_name`: The name of the enumeration type
- `constant1, constant2, constant3, ...`: Named constants within the enum

Here's another example where one of the constants is assigned a value:
**Return value:**

```cpp
enum grade {freshman=9, sophomore, junior, senior};
```
Enums do not return values directly. They define a new data type that can be used to create variables.

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.
## Example 1: Basic Enum Creation

So here:
This example demonstrates how to create a simple enum and use it in a program:

- `freshman` would have the value 9
- `sophomore` would have the value 10
- `junior` would have the value 11
- `senior` would have the value 12

## Codebyte Example

```codebyte/cpp
```cpp
#include <iostream>
using namespace std;

// Define an enum for days of the week
enum Day {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
};

int main() {
enum quarter_one {
january=1,
february,
march
};
// Create an enum variable
Day today = WEDNESDAY;

int month = february;
// Output the enum value
cout << "Today is day number: " << today << endl;

std::cout << month;
return 0;
}
```

## Scoped Enums
The output of this code is:

Scoped enums are a feature added in C++11.
```shell
Today is day number: 2
```

Scoped enums differ from unscoped enums by:
In this example, we define an enum called `Day` with seven constants representing days of the week. By default, `MONDAY` gets the value 0, `TUESDAY` gets 1, and so on. We then create a variable `today` of type `Day` and assign it the value `WEDNESDAY`, which has the integer value 2.

- 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 2: Changing Values in Enum

## Example
This example shows how to assign custom values to enum constants:

```cpp
enum class WeekDay {sun, mon, tue, wed, thu, fri, sat};
#include <iostream>
using namespace std;

// Define an enum with custom values
enum Priority {
LOW = 1,
MEDIUM = 5,
HIGH = 10,
URGENT = 15
};

WeekDay day = WeekDay::sun; // Notice that "sun" is prefaced with "Weekday::"
int friday = WeekDay::fri; // error, must cast to an int
```
int main() {
// Create enum variables
Priority taskPriority = HIGH;
Priority alertLevel = URGENT;

Here's an example where scoped enumerations avoid name collisions:
// Display the values
cout << "Task priority: " << taskPriority << endl;
cout << "Alert level: " << alertLevel << endl;

```cpp
enum class LogResult {Success, InvalidFileName, WriteError};
enum class SocketResult {Success, InvalidAddrError, TimeoutError};
// Compare enum values
if (alertLevel > taskPriority) {
cout << "Alert level is higher than task priority" << endl;
}

return 0;
}
```

LogResult logger_result = LogResult::Success;
The output of this code is:

if (logger_result == LogResult::Success) {} // Because Success is scoped to LogResult, it doesn't collide with SocketResult::Success
```shell
Task priority: 10
Alert level: 15
Alert level is higher than task priority
```

## Enum to Int Conversion
This example demonstrates how to assign specific integer values to enum constants. When you set a value for one constant, subsequent constants automatically increment from that value unless explicitly assigned. Here, `LOW` is 1, `MEDIUM` is 5, `HIGH` is 10, and `URGENT` is 15.

In C++, `enum` can be implicitly converted to integers, useful for numeric contexts like array indexing or bitwise operations:
## Example 3: Enum in a Switch Statement

This example demonstrates using enums with switch statements for control flow:

```cpp
#include <iostream>
enum color { red, green, blue };
using namespace std;

// Define an enum for traffic light colors
enum TrafficLight {
RED,
YELLOW,
GREEN
};

int main() {
color c = green;
int colorValue = c; // Implicit conversion to int
std::cout << "Color value: " << colorValue;
TrafficLight currentLight = RED;

// Use enum in switch statement
switch (currentLight) {
case RED:
cout << "Stop! Red light is on." << endl;
break;
case YELLOW:
cout << "Caution! Yellow light is on." << endl;
break;
case GREEN:
cout << "Go! Green light is on." << endl;
break;
default:
cout << "Unknown light state." << endl;
}

// Simulate traffic light sequence
cout << "\nTraffic light sequence:" << endl;
for (int i = RED; i <= GREEN; i++) {
TrafficLight light = static_cast<TrafficLight>(i);
switch (light) {
case RED:
cout << "RED -> ";
break;
case YELLOW:
cout << "YELLOW -> ";
break;
case GREEN:
cout << "GREEN";
break;
}
}
cout << endl;

return 0;
}
```

Here is the output:
The output generated by this code is:

```shell
Color value: 1
Stop! Red light is on.

Traffic light sequence:
RED -> YELLOW -> GREEN
```

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.
This example shows how enums work perfectly with switch statements, providing clear and readable control flow. The enum values make the code self-documenting and easier to maintain than using magic numbers.

## Custom Underlying Types
## Codebyte Example: Create Enum Class

By default, an enum's type is `int`, but a smaller type like `unsigned char` can be specified to optimize memory usage:
This example demonstrates scoped enums (enum class) introduced in C++11, which provide better type safety and scope control:

```cpp
```codebyte/cpp
#include <iostream>
enum class Permission : unsigned char {
Read = 1,
Write = 2,
Execute = 4
using namespace std;

// Define enum class for better type safety
enum class Color {
RED,
GREEN,
BLUE
};

enum class Size {
SMALL,
MEDIUM,
LARGE
};

int main() {
Permission p = Permission::Write;
std::cout << static_cast<int>(p); // Explicit cast to int
// Create enum class variables
Color favoriteColor = Color::RED;
Size shirtSize = Size::MEDIUM;

// Display enum class values (requires casting)
cout << "Favorite color code: " << static_cast<int>(favoriteColor) << endl;
cout << "Shirt size code: " << static_cast<int>(shirtSize) << endl;

// Enum class prevents implicit conversions
// This would cause compilation error:
// if (favoriteColor == Size::SMALL) { ... }

// Use enum class in switch statement
switch (favoriteColor) {
case Color::RED:
cout << "You chose red color!" << endl;
break;
case Color::GREEN:
cout << "You chose green color!" << endl;
break;
case Color::BLUE:
cout << "You chose blue color!" << endl;
break;
}

return 0;
}
```

Here, the underlying type of `Permission` is `unsigned char`. The constants `Read`, `Write`, and `Execute` are stored using only 1 byte of memory.
**Enum class** provides several advantages over regular enums: they are strongly typed (no implicit conversion to integers), they don't pollute the surrounding namespace, and they prevent naming conflicts. You must use the scope resolution operator (`::`) to access enum class values.

This example results in the following output:
## Frequently Asked Questions

```shell
2
```
### 1. Why use enum instead of array?

Enums are used to define a set of named constants that represent fixed values, while arrays store collections of data. Enums provide compile-time constants that make code more readable and maintainable. Unlike arrays, enums don't allocate memory for storing values at runtime - they're purely symbolic names for integer constants.

### 2. How to get enum value in C++?

You can get the integer value of an enum by simply using the enum constant in an integer context or by explicitly casting it. For regular enums, implicit conversion to int works, but for enum classes, you need `static_cast<int>(enum_value)`.

### 3. Can enum values be strings?

## Best Practices
No, enum values in C++ are always integers. However, you can create arrays or maps to associate enum values with strings for display purposes.

Here are some best practices for using enums:
### 4. What's the difference between enum and enum class?

1. Use `enum class` for strong typing: Scoped enums (C++11) prevent implicit int conversions, ensuring better type safety.
2. Explicit casting: Use `static_cast<int>(enum_value)` for safe conversions.
3. Avoid magic numbers: Enums replace hardcoded numbers, improving readability.
4. Use underlying types wisely: Choose the underlying type carefully in memory-constrained environments.
`enum class` (scoped enums) introduced in C++11 provides better type safety, doesn't pollute the namespace, and prevents implicit conversions. Regular enums allow implicit conversion to integers and their constants are accessible without scope resolution.