[英]How do I switch over an enum class?
Enum classes are supposed to be strong enums in the sense that they don't implicitly convert to and from int
.枚举类应该是强枚举,因为它们不会隐式转换为 int 或从int
转换。 For instance:例如:
enum class EC { a, b };
However, when switching over such a "strong enum":但是,当切换这样一个“强枚举”时:
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
}
gcc -Wreturn-type
-wants me to add a default
clause to the switch even though all legal enum values are covered: gcc -Wreturn-type
希望我在开关中添加一个default
子句,即使涵盖了所有合法的枚举值:
warning: control reaches end of non-void function [-Wreturn-type]
In an old (non-class) enum, this makes sense, because any int
could have been accidentally converted to EC
.在旧的(非类)枚举中,这是有道理的,因为任何int
都可能被意外转换为EC
。 But I had (apparently wrongly) assumed that assigning an invalid enum member to an enum class was UB.但是我(显然错误地)假设将无效的枚举成员分配给枚举 class 是 UB。
How can I use truly strong enum classes where the compiler realises that functions like sw
cover all possible paths?在编译器意识到像sw
这样的函数涵盖所有可能的路径的情况下,如何使用真正强大的枚举类? Of course I could just add a default:
branch that I know will never be triggered, but I want to make sure that adding more members to EC
in the future will trigger a warning in the switch .当然,我可以添加一个我知道永远不会触发的default:
分支,但我想确保将来向EC
添加更多成员会在 switch 中触发警告。
You can return a dummy variable, to remove the "control reaches end of non-void function".您可以返回一个虚拟变量,以删除“控制到达非无效函数的结尾”。 This way, the warning is removed, and any additions to the enum-class will still trigger a warning in the switch statement:这样,警告就被删除了,对 enum-class 的任何添加仍然会在 switch 语句中触发警告:
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
return 0; //dummy variable
}
"control reaches end of non-void function" is quite different from common "enumeration value 'c' not handled in switch [-Wswitch]" warning. “控制到达非无效函数的结尾”与常见的“枚举值'c'未在开关 [-Wswitch] 中处理”警告完全不同。 I think compiler is being a bit too cautious here, but this warning may turn out to be handy because it will prevent potential future UB caused by modification of enum
and ignoring of -Wswitch
warning.我认为编译器在这里有点过于谨慎,但这个警告可能会变得很方便,因为它可以防止由于修改enum
和忽略-Wswitch
警告而导致的潜在未来 UB。
Rewriting this snippet like this would make code future proof:像这样重写此代码段将使代码面向未来:
enum class EC { a, b /*,c */ };
int sw(EC ec) {
int result{};
switch (ec) { // warning: enumeration value 'c' not handled in switch [-Wswitch]
case EC::a: result = 0; break;
case EC::b: result = 1; break;
}
return result; // control flow will always leave function properly
}
A enum
variable - both old-school one and enum class
can hold values that are not one of the members of the enumeration. enum
变量 - 老式变量和enum class
都可以保存不是枚举成员之一的值。 As long as the integer value fits within the underlying type (with a few more restrictions), it is valid to store it in the enumeration type.只要 integer 值符合基础类型(还有一些限制),就可以将其存储在枚举类型中。
This worked for me:这对我有用:
enum class EC {a, b, c};
int sw (EC ec)
{
int rc;
switch (ec)
{
case EC::a:
rc = 0;
break;
case EC::b:
rc = 1;
break;
}
return rc;
}
In GCC/Clang/ICC you can silence this warning with __builtin_unreachable()
:在 GCC/Clang/ICC 中,您可以使用__builtin_unreachable()
此警告:
int sw(EC ec) {
switch (ec) {
case EC::a: return 0;
case EC::b: return 1;
}
assert(false);
__builtin_unreachable();
}
In MSVC __assume(0)
can be used.在 MSVC 中可以使用__assume(0)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.