【问题标题】:Safely convert int to enum安全地将 int 转换为 enum
【发布时间】:2015-07-28 13:06:09
【问题描述】:

我想知道是否有任何巧妙的技巧可以安全地将整数转换为枚举。在你投票认为这是重复的之前,我不是在问如何转换(int i; Enum e = static_cast<Enum>(i) 很容易)。我在问如何安全地做到这一点,验证结果值确实在枚举中。

以下代码

enum class E {
    A = 1,
    B = 2
};

int main(int, char **) {
    int i = 3;
    E e = static_cast<E>(i);
}

将编译 (AFAIK) 但e 将不包含来自枚举的有效值。我想出的最好方法是

switch (i) {
    case 1:
        return E::A;
    case 2:
        return E::B;
    default:
        throw invalid_argument("");
}

which 1) 看起来不太聪明 2) 不能很好地扩展。我可能可以组合一些宏来简化此操作,但它仍然看起来很笨。

那么有什么“标准”的方法可以做到吗?

谢谢

【问题讨论】:

  • 也许this answer 有帮助? (使用类枚举确保只允许指定的值,AFAIK)
  • 除非你有办法获得枚举大小(例如enum class E{A=0, B, ENUM_COUNT};,其中ENUM_COUNT 将给出2,并且枚举是正数并且从0 开始增加,那么答案是否定的。枚举非常原始。请参阅 SO 上有关克服这些问题的许多其他问题。一些基于宏的方法很好,我不禁插入我自己的问题 here,它有一些有用的答案和建议可以帮助你。
  • 别以为你能做到。C++ 程序不是为了“感知”它们的内容而构建的,它只会执行盲代码
  • 验证值的方式还取决于枚举的预期用途。从技术上讲,A | B 是您的枚举的有效值(但可能不适用于应用程序)。
  • “我在问如何安全地做到这一点,验证结果值确实在枚举中。” 您正在使用 C++ 中的“安全”的个人定义标准和编译器不同意。对于不对应于该类型的枚举数之一的枚举类型的值,没有什么“不安全”的。给定enum E { max=255 }; 那么E{1} 是一个有效值,并且完全“安全”。如果你想要一个只能接受特定值的类型,那么你不应该使用枚举类型。

标签: c++ c++11 enums


【解决方案1】:

如果您也不必转换数值,我会建议类似

switch (i)
{
    case static_cast<int>(E::A):
    case static_cast<int>(E::B):
        return static_cast<E>(i);
    default:
        throw invalid_argument("");
}

至少这可以防止一些常见错误,例如忘记更改大小写或返回值,或者只是查找错误的数值。此外,它对重构更加友好(考虑更改数值 - 毕竟您定义了一个枚举,以便您不必在多个位置更改值)。

不幸的是,这仍然不是很好,但这是我所知道的最好的方式。好吧,除非你想使用X macros

【讨论】:

  • 嘿,我没想到。丑得要命,但可能是最好的方法。谢谢。 X 宏看起来……很有趣。不确定我是否喜欢它,但它也可能有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
相关资源
最近更新 更多