I am finding that all of my standard techniques for iterating over regular enum
s unfortunately do NOT work on enum class
es since enum classes do not implicitly convert to integers.
NOT a duplicate of How can I iterate over an enum?, since I'm asking about an enum class
(ie: a strongly-typed enum) and they are asking about a regular enum
(ie: a weakly-typed enum).
CodePudding user response:
This is the most-readable and simplest approach I could come up with, but I am open to other peoples' example solutions.
I find this approach to be easy-to-use, similar to my C approach (making it more-portable and more-recognizable), and suitable to C . It compiles with the -Wall -Wextra -Werror
compiler build options.
enum class MyErrorType
{
SOMETHING_1 = 0,
SOMETHING_2,
SOMETHING_3,
SOMETHING_4,
SOMETHING_5,
/// Not a valid value; this is the number of members in this enum
_COUNT,
};
for (MyErrorType myErrorType = (MyErrorType)0;
myErrorType < MyErrorType::_COUNT;
myErrorType = static_cast<MyErrorType>((size_t)myErrorType 1))
{
switch (myErrorType)
{
case MyErrorType::SOMETHING_1:
break;
case MyErrorType::SOMETHING_2:
break;
case MyErrorType::SOMETHING_3:
break;
case MyErrorType::SOMETHING_4:
break;
case MyErrorType::SOMETHING_5:
break;
case MyErrorType::_COUNT:
// this case will never be reached. It is included only so that when
// compiling with `-Wall -Wextra -Werror` build flags you get the
// added bonus of covering all switch cases, so if you ever add a
// new element to the enum class but forget to add it here to the
// switch case the compiler will THROW AN ERROR. This is an added
// safety benefit to force you to keep your enum and the switch
// statement in-sync! It's a technique commonly used in C as well.
break;
}
}
Read my comments for the MyErrorType::_COUNT
case above! If you are using the compiler's -Wall -Wextra -Werror
compiler options but do NOT include this case in the switch statement (since those build options require you to cover ALL enum cases in ALL switch statements!), the compiler will throw the following error and stop! This is a great safety feature to ensure you keep the enum definition and all switch cases in-sync, handling all possible enums in all of your switch statements. Here is the compiler error thrown by LLVM's clang compiler (an alternative to gcc):
../my_file.cpp:11:16: error: enumeration value ‘_COUNT’ not handled in switch [-Werror=switch] 11 | switch (myErrorType) { | ^
Related:
- Common techniques for iterating over
enum
s (as opposed toenum class
es): How can I iterate over an enum? - My answer on some of the differences between
enum class
es (strongly-typed enums) and regularenum
s (weakly-typed enums) in C : How to automatically convert strongly typed enum into int? - Some of my personal notes on the
-Wall -Wextra -Werror
and other build options, from my eRCaGuy_hello_world repo.
Other keywords: common way to iterate over enum or enum class in C or C ; best way to iterate over enum class in C ; enum class C iterate; c iterate over enum class
CodePudding user response:
Another alternative is to use C 20 ranges to compose an enum
range:
constexpr inline auto enum_range = [](auto front, auto back) {
return std::views::iota(std::to_underlying(front), std::to_underlying(back) 1)
| std::views::transform([](auto e) { return decltype(front)(e); });
};
Then you can iterate the enum
like this:
enum class color { red, yellow, green, blue };
for (const auto e : enum_range(color::red, color::blue))
// ...