如何切换枚举类?

时间:2020-04-25 14:45:20

标签: c++ switch-statement strong-typing enum-class defensive-programming

枚举类应该是强枚举,因为它们不会隐式地与int之间进行转换。例如:

enum class EC { a, b };

但是,当切换这样的“强枚举”时:

int sw(EC ec) {
  switch (ec) {
    case EC::a: return 0;
    case EC::b: return 1;
  }
}

gcc -Wreturn-type-希望我在交换机上添加一个default子句,即使涵盖了所有合法的枚举值:

warning: control reaches end of non-void function [-Wreturn-type]

在旧的(非类)枚举中,这是有道理的,因为任何int都可能被意外地转换为EC。但是我(显然是错误的)认为将无效的枚举成员分配给枚举类是UB。

在编译器意识到sw之类的函数覆盖所有可能的路径的情况下,如何使用真正强大的枚举类?当然,我可以只添加一个我知道永远不会被触发的default:分支,但是我希望确保将来将更多成员添加到EC 在开关中触发警告

5 个答案:

答案 0 :(得分:1)

您可以返回一个虚拟变量,以删除“控制到达非void函数的末尾”。这样,警告将被删除,并且对enum-class的任何添加仍将在switch语句中触发警告:

int sw(EC ec) {
  switch (ec) {
    case EC::a: return 0;
    case EC::b: return 1;
  }

  return 0; //dummy variable
}

答案 1 :(得分:1)

“控制到达非空函数的末尾”与常见的“在开关[-Wswitch]中未处理的枚举值'c'”警告完全不同。我认为编译器在此过于谨慎,但此警告似乎很方便,因为它将防止由于修改enum并忽略-Wswitch警告而引起的潜在未来UB。

以这种方式重写此代码段将使代码成为将来的证明:

online compiler

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
}

答案 2 :(得分:0)

一个enum变量-老一和enum class都可以容纳不是枚举成员之一的值。只要整数值适合基础类型(还有更多限制),将其存储在枚举类型中是有效的。

答案 3 :(得分:0)

这对我有用:

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;
}

答案 4 :(得分:0)

在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();
}

在MSVC中可以使用__assume(0)