Summary
Question:
is there a way to convert a strongly typed enum value into an integer type without a cast? If yes, how?
Answer:
No, there is not. Strongly typed enums can NOT be converted to integers without an explicit cast. Weak enums can, however, as they will be automatically implicitly cast. So, if you'd like automatic implicit conversion to an int, consider using a C-style weak enum instead (see more on this in the "Going further" section below).
From here (emphasis added): https://en.cppreference.com/w/cpp/language/enum --> under the section "Scoped enumerations":
There are no implicit conversions from the values of a scoped enumerator [AKA: "strong enum"] to integral types, although static_cast
may be used to obtain the numeric value of the enumerator.
Going further: discussion of weak (C-style) vs strong (C++ enum class
) enum types in C++
In C++ there are two types of enums:
- "unscoped", "regular", "weak", "weakly typed", or "C-style" enums, and
- "scoped", "strong", "strongly typed", "enum class", or "C++-style" enums.
"Scoped" enums, or "strong" enums, give two additional "features" beyond what "regular" enums give you.
Scoped enums:
- don't allow implicit casting from the enum type to an integer type (so you can't do what you want to do implicitly!), and
- they "scope" the enum so that you have to access the enum through its enum type name.
1. Example of an enum class (available only in C++):
// enum class (AKA: "strong" or "scoped" enum)
enum class my_enum
{
A = 0,
B,
C,
};
my_enum e = my_enum::A; // scoped through `my_enum::`
e = my_enum::B;
// NOT ALLOWED!:
// error: cannot convert ‘my_enum’ to ‘int’ in initialization
// int i = e;
// But explicit casting works just fine!:
int i1 = static_cast<int>(e); // explicit C++-style cast
int i2 = (int)e; // explicit C-style cast
The first "feature" may actually be something you don't want, in which case you just need to use a regular C-style enum instead! And the nice thing is: you can still "scope" or "namespace" the enum, as has been done in C for decades, by simply prepending its name with the enum type name, like this:
2. Example of a regular enum (available in both C and C++):
// regular enum (AKA: "weak" or "C-style" enum)
enum my_enum
{
// C-style-scoped through the `MY_ENUM_` prefix
MY_ENUM_A = 0,
MY_ENUM_B,
MY_ENUM_C,
};
my_enum e = MY_ENUM_A; // scoped through `MY_ENUM_`
e = MY_ENUM_B;
// This works fine!
int i = e;
Notice you still get the benefit of "scoping" simply by adding the MY_ENUM_
"scope" to the front of each enum!
3. Both regular enums and enum classes together:
Test the code here: https://onlinegdb.com/BkWGqlqz_.
main.cpp:
#include <iostream>
#include <stdio.h>
// enum class (AKA: "strong" or "scoped" enum [available only in C++, not C])
enum class my_enum
{
A = 0,
B,
C,
};
// regular enum (AKA: "weak" or "C-style" enum [available in BOTH C and C++])
enum my_enum2
{
MY_ENUM_A = 0,
MY_ENUM_B,
MY_ENUM_C,
};
int main()
{
printf("Hello World\n");
// 1) scoped enum
my_enum e = my_enum::A; // scoped through `my_enum::`
e = my_enum::B;
// IMPLICIT CASTING TO INT IS NOT ALLOWED!
// int i = e; // "error: cannot convert ‘my_enum’ to ‘int’ in initialization"
// But this explicit C++-style cast works fine:
int i1 = static_cast<int>(e);
// This explicit C-style cast works fine too, and is easier to read
int i2 = (int)e;
// 2) regular enum
my_enum2 e2 = MY_ENUM_A; // scoped through `MY_ENUM_`
e2 = MY_ENUM_B;
// This implicit cast works fine / IS allowed on C-style enums!
int i3 = e2;
// These explicit casts are also fine, but explicit casting is NOT
// required for regular enums.
int i4 = static_cast<int>(e2); // explicit C++-style cast
int i5 = (int)e2; // explicit C-style cast
return 0;
}
4. How to iterate over enums:
- *****[my answer] Full examples of how to iterate over both 1. weakly-typed C-style and 2. scoped, strongly-typed C++
enum class
enums: How can I iterate over an enum?
- [my Q&A] What are commonly-used ways to iterate over an enum class in C++?