这是我能想到的最易读和最简单的方法,但我愿意接受其他人的示例解决方案。
我发现这种方法易于使用,类似于我的 C 方法(使其更便携和更易识别),并且适用于 C++。它使用-Wall -Wextra -Werror 编译器构建选项进行编译。
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,
// helpers for iterating over the enum
begin = 0,
end = _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 (withOUT unnecessarily
// relying on a `default` case which would break this feature!), 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;
}
}
请阅读我的 cmets 以了解上述 MyErrorType::_COUNT 案例!如果您使用编译器的 -Wall -Wextra -Werror 编译器选项,但不要在 switch 语句中包含这种情况(因为这些构建选项要求您在所有 switch 语句中涵盖所有枚举情况!),编译器将抛出以下错误并停止!这是一个很好的安全功能,可确保您保持枚举定义和所有 switch case 同步,处理所有 switch 语句中的所有可能枚举。这是 LLVM 的 clang 编译器(gcc 的替代品)引发的编译器错误:
../my_file.cpp:11:16: error: enumeration value ‘_COUNT’ not handled in switch [-Werror=switch]
11 | switch (myErrorType) {
| ^
为了清楚起见,对上述代码的另一个微小改进是将begin 和end 元素添加到您的枚举中,如下所示:
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,
// helpers for iterating over the enum
begin = 0,
end = _COUNT,
};
...这样您就可以按如下方式遍历枚举。 for 循环的递增部分对于所有必需的转换仍然有点麻烦,但初始状态和结束条件检查现在至少更清晰了,因为它们使用 MyErrorType::begin 和 MyErrorType::end:
for (MyErrorType myErrorType = MyErrorType::begin;
myErrorType < MyErrorType::end;
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.
break;
}
}
相关:
- 迭代
enums(相对于enum classes)的常用技术:How can I iterate over an enum?
- [我的回答]How can I iterate over an enum?
- 我对 C++ 中
enum classes(强类型枚举)和常规 enums(弱类型枚举)之间的一些差异的回答: How to automatically convert strongly typed enum into int?
-
Some of my personal notes on the
-Wall -Wextra -Werror and other build options,来自我的 eRCaGuy_hello_world 存储库。
- Incrementation and decrementation of “enum class”
其他关键字:在 C 或 C++ 中迭代枚举或枚举类的常用方法;在 C++ 中迭代枚举类的最佳方法;枚举类 C++ 迭代; c++遍历枚举类