C++ 从整数构造强类型枚举的正确方法

C++ 从整数构造强类型枚举的正确方法,c++,c++11,enums,C++,C++11,Enums,假设static\u cast(userInt)如果未映射userInt可能导致未定义的行为,那么从用户输入的整数构造强类型枚举的正确方法是什么 另外,如果输入的值没有映射到枚举中,我想将其设置为默认值 一种解决办法是: switch (userInt) { case 1: selEnum = myEnum1; break; case 2: selEnum = myEnum2; break; default:

假设
static\u cast(userInt)
如果未映射
userInt
可能导致未定义的行为,那么从用户输入的整数构造强类型枚举的正确方法是什么

另外,如果输入的值没有映射到枚举中,我想将其设置为默认值

一种解决办法是:

switch (userInt)
{
    case 1:
        selEnum = myEnum1;
        break;
    case 2:
        selEnum = myEnum2;
        break;
    default:
        selEnum = myEnum2;
        error = true;
        break;
}

但我不喜欢这样,如果我更改了枚举值,我必须记住更新它。

您可以轻松测试整数是否在基础类型的范围内,然后在枚举值上使用开关

MyEnum convert_from_untrusted_int(int userInt)
{
    using limits = std::numeric_limits<std::underlying_type_t<MyEnum>>>;

    auto const defaultValue = myEnum2;

    if (userInt < limits.min() || userInt > limits.max())
        return defaultValue;

    auto const e = MyEnum(userInt);
    switch (e) {
      case myEnum1:
      case myEnum2:  // compiler will warn if we miss one
        return e;
    }
    // we only get here if no case matched
    return defaultValue;
}
MyEnum从不受信任的int(int-userInt)转换
{
使用限制=标准::数字限制>;
auto const defaultValue=myEnum2;
if(userIntlimits.max())
返回默认值;
auto const e=MyEnum(userInt);
开关(e){
病例1:
case myEnum2://如果我们错过了一个,编译器将发出警告
返回e;
}
//我们只有在没有匹配的情况下才能到达这里
返回默认值;
}

当然,这取决于您是否使用了足够的编译器警告,提示将在
开关中拾取丢失的枚举数。

为什么您认为这是UB?只有当输入超出枚举的基础类型的范围时,该值才是未指定的,因此您可以轻松地进行验证。或者,您的意思是要将输入限制为已定义枚举数的值?正是@Praetorian。我想检测该值是否未定义,并将其设置为默认值。编辑该值以显式命名将使用的上下文。只有在预处理器(如boost.preprocessor)的帮助下,才能实现您的目标(在C++20反射之前)。您可以使用BOOST_PP_SEQ_enum和一个验证实际值的函数来定义枚举值列表