在 C++ 中,枚举是不安全的。您不能期望枚举值是枚举声明中定义的值之一:
- 它可能未初始化(因此是垃圾)
- 你可能有不正当
static_cast
的int
因此,即使您覆盖了枚举的所有元素,编译器也不能期望开关返回。但是,从功能上讲,它确实是一个错误条件。
有两种反应方式:
- 将
default
案例添加到您的enum
- 在 switch 后添加语句
为了明智地选择,请记住,只要 aswitch
没有涵盖 a 的所有情况,编译器可能(如果您要求它)enum
在没有default
语句的情况下触发警告。智能编译器(即 Clang)允许将警告单独映射到错误,这极大地有助于捕获这些错误。
因此,您有一个决定:
- 如果您想在更新枚举后忘记更改此方法时收到通知,请不要使用
default
- 如果您希望能够更新枚举并忽略此开关,请使用
default
最后,您必须决定如何做出反应,注意使用运行时错误与使用默认语句不一致(最好尽可能在编译时捕获错误):
- 忽略错误并返回一些预定义的值
- 抛出异常(请使用枚举值)
- 断言(因此在调试中严重崩溃,以获取内存转储,并在发布时执行其他操作,例如什么也不做,或抛出异常)
我个人最喜欢的是一个UNREACHABLE(Text_)
宏,它会在 Debug 中引发内存转储(以便我获得完整的跟踪)并记录错误并在 Release 中抛出(以便服务器停止处理此请求,但不会完全停止响应)。
这给出了这样的代码:
char const* func(ENUM x)
{
switch(x)
{
case Option1: return "Option1";
case Option2: return "Option2";
case Option3: return "Option3";
}
UNREACHABLE("func(ENUM)")
}