字符串到枚举的失败证明转换 class

fail proof conversion of string to enum class

我有一个像这样的枚举 class(我打算稍后添加更多选项):

enum class ViSequencePointType {
   JumpToValue = 0,
   RampToValue = 1
};

然后我有一个配置文本文件,其中每一行都应该代表一个枚举值。像这样:

1
0
255
A
WTF

我需要解析此文件并创建该枚举的向量 class...所以我会执行以下操作:

    bool conversionResult = false;
    int colThree = line.toInt(&conversionResult);
    if(!conversionResult) { 
         //failed to convert to integer
    } else {
    ViSequencePointType pt = static_cast<ViSequencePointType>(colThree);
    switch(pt) {
        case ViSequencePointType::JumpToValue:
            break;
        case ViSequencePointType::RampToValue:
            break;
        default:
            break;
    }

对于 default 的情况,编译器说

Default label in switch which covers all enumeration values

我相信这意味着如果文本文件中存在任何无效条目,我找不到它!

那么如何在 运行时 期间不让任何无效枚举溜走的情况下解决这个问题?

为了覆盖 invalid/nonsensical 枚举值,通常的做法是

  • 基于以下事实,后续枚举值被隐式分配为前一个枚举值的值 + 1
  • 在枚举中的最低值处添加一个 "Invalid" 枚举值(隐式为 0,或者您可以为其分配一个较低的值,例如 -1
  • 在枚举中的最高值处添加一个"Max"枚举值

这是一个例子:

enum class ViSequencePointType 
{
    Invalid = -1,

    JumpToValue,            // is implicitly assigned enum value 0 (-1 + 1 == 0)
    RampToValue,            // is implicitly 1 (JumpToValue + 1)
    CrawlToValue,           // etc...
    HopToValue,    
    // add new values here       

    Max                     // Max must be the last value in the enum
};

现在,当您解析输入值时,您可以检查整数值是否大于 Invalid 且小于 Max,如果是这样,您就知道它是一个有效的枚举值

ViSequencePointType parse(const std::string& value)
{
    bool converted = false;
    int val = line.toInt(&converted);
    if(!converted) 
    { 
         // do additional conversion failure handling here if necessary
         return ViSequencePointType::Invalid;
    } 
    if (val <= static_cast<int>(ViSequencePointType::Invalid) ||
        val >= static_cast<int>(ViSequencePointType::Max)
    {
         // do additional out of bounds handling here if necessary
         return ViSequencePointType::Invalid;
    }
    return static_cast<ViSequencePointType>(val);
}

现在您知道 parse 的输出是一个有效的枚举值,unknown/invalid 值的输出由枚举值 Invalid.

表示