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

时间:2019-02-19 12:23:53

标签: c++ qt c++11 enums enum-class

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

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 :(得分:1)

为了覆盖无效/无意义的枚举值,通常的做法是

  • 基于事实,随后的枚举值被隐式地分配了先前的枚举值+ 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的输出是有效的枚举值,未知/无效值的输出由枚举值Invalid表示。