Gab*_*les 5 c++ enums enumeration enum-class
不幸的是,我发现迭代常规 s 的所有标准技术enum
都不适用于enum class
es,因为枚举类不会隐式转换为整数。
不是如何迭代枚举?,因为我询问的是 an enum class
(即:强类型枚举),而他们询问的是常规enum
(即:弱类型枚举)。
另一种替代方法是使用 C++20 范围来组成enum
范围:
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); });
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样迭代enum
:
enum class color { red, yellow, green, blue };
for (const auto e : enum_range(color::red, color::blue))
// ...
Run Code Online (Sandbox Code Playgroud)
这是我能想到的最易读和最简单的方法,但我对其他人的示例解决方案持开放态度。
\n我发现这种方法易于使用,类似于我的 C 方法(使其更便携且更易于识别),并且适合 C++。它使用-Wall -Wextra -Werror
编译器构建选项进行编译。
enum class MyErrorType \n{\n SOMETHING_1 = 0,\n SOMETHING_2,\n SOMETHING_3,\n SOMETHING_4,\n SOMETHING_5,\n /// Not a valid value; this is the number of members in this enum\n _COUNT,\n // helpers for iterating over the enum\n begin = 0,\n end = _COUNT,\n};\n\nfor (MyErrorType myErrorType = (MyErrorType)0; \n myErrorType < MyErrorType::_COUNT;\n myErrorType = static_cast<MyErrorType>((size_t)myErrorType + 1)) \n{\n switch (myErrorType) \n {\n case MyErrorType::SOMETHING_1:\n break;\n case MyErrorType::SOMETHING_2:\n break;\n case MyErrorType::SOMETHING_3:\n break;\n case MyErrorType::SOMETHING_4:\n break;\n case MyErrorType::SOMETHING_5:\n break;\n case MyErrorType::_COUNT:\n // This case will never be reached. It is included only so that when\n // compiling with `-Wall -Wextra -Werror` build flags you get the\n // added bonus of covering all switch cases (withOUT unnecessarily\n // relying on a `default` case which would break this feature!), so\n // if you ever add a new element to the enum class but forget to\n // add it here to the switch case the compiler will THROW AN ERROR.\n // This is an added safety benefit to force you to keep your enum\n // and the switch statement in-sync! It\'s a technique commonly used\n // in C as well.\n break;\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n阅读我对MyErrorType::_COUNT
上述案例的评论!如果您正在使用编译器的-Wall -Wextra -Werror
编译器选项,但不在 switch 语句中包含这种情况(因为这些构建选项要求您覆盖所有 switch 语句中的所有枚举情况!),编译器将抛出以下错误并停止!这是一个很好的安全功能,可确保您保持枚举定义和所有 switch 情况同步,处理所有 switch 语句中所有可能的枚举。这是 LLVM 的clang编译器( gcc的替代方案)抛出的编译器错误:
\n\nRun Code Online (Sandbox Code Playgroud)\n../my_file.cpp:11:16: error: enumeration value \xe2\x80\x98_COUNT\xe2\x80\x99 not handled in switch [-Werror=switch]\n 11 | switch (myErrorType) {\n | ^\n
为了清楚起见,对上面代码的另一个微小改进是将begin
和end
元素添加到您的枚举中,如下所示:
../my_file.cpp:11:16: error: enumeration value \xe2\x80\x98_COUNT\xe2\x80\x99 not handled in switch [-Werror=switch]\n 11 | switch (myErrorType) {\n | ^\n
Run Code Online (Sandbox Code Playgroud)\n...这样您就可以按如下方式迭代枚举。对于所有必需的强制转换,循环的递增部分for
仍然有点麻烦,但初始状态和结束条件检查现在至少更加清晰,因为它们使用了MyErrorType::begin
and MyErrorType::end
:
enum class MyErrorType \n{\n SOMETHING_1 = 0,\n SOMETHING_2,\n SOMETHING_3,\n SOMETHING_4,\n SOMETHING_5,\n /// Not a valid value; this is the number of members in this enum\n _COUNT,\n // helpers for iterating over the enum\n begin = 0,\n end = _COUNT,\n};\n
Run Code Online (Sandbox Code Playgroud)\nenum
s(而不是enum class
es)的常用技术:如何迭代枚举?\nenum class
es(强类型枚举)和常规enum
s(弱类型枚举)之间的一些差异的回答:如何自动将强类型枚举转换为 int?-Wall -Wextra -Werror
我关于和其他构建选项的一些个人笔记,来自我的eRCaGuy_hello_world存储库。其他关键字:C或C++中迭代enum或enum类的常用方式;在 C++ 中迭代枚举类的最佳方法;枚举类 C++ 迭代;C++ 迭代枚举类
\n 归档时间: |
|
查看次数: |
7674 次 |
最近记录: |