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

fail proof conversion of string to enum class

本文关键字:枚举 字符串 转换 证明 失败      更新时间:2023-10-16

我有这样的枚举类(我打算稍后再添加更多选项):

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

然后,我有一个配置文本文件,每行应该代表一个枚举值。这样的东西:

1
0
255
A
WTF

我需要解析此文件并创建一个枚举类的向量...所以我做类似的事情:

    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案例,编译器说

开关中的默认标签,该标签涵盖了所有枚举值

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

那么,如何在运行时

期间让任何无效的枚举在不让任何无效的枚举中解决这个问题。

为了涵盖无效/毫无意义的枚举值,一种常见的做法是

  • 依靠随后的枚举值被隐式分配了先前的枚举值 1
  • 的值
  • 在枚举中以最低值(隐式为0)添加"Invalid"枚举值,或者您可以为其分配一个低值,例如-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的输出是一个有效的枚举值,未知/无效值的输出用枚举值Invalid