Безошибочное преобразование строки в перечисляемый класс

У меня есть такой класс enum (я планирую добавить в него больше опций позже):

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

Затем у меня есть текстовый файл конфигурации, который каждая строка должна представлять одно из значений перечисления. Что-то вроде этого:

1
0
255
A
WTF

Мне нужно проанализировать этот файл и создать вектор этого enum-класса... поэтому я делаю что-то вроде:

    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 в случае, если компилятор говорит

Метка по умолчанию в switch, которая охватывает все значения перечисления

что я считаю, что это означает, что если в текстовом файле существует недопустимая запись, я не могу это выяснить!

Итак, как я могу решить эту проблему, не допуская недопустимого перечисления во время выполнения?

0 ответов

Для того, чтобы охватить недействительные / бессмысленные значения перечисления, обычной практикой является

  • полагаться на то, что последующим значениям перечисления неявно присваивается значение предыдущего значения перечисления + 1
  • добавить "Invalid" значение enum с самым низким значением в enum (неявно 0, или вы можете присвоить ему низкое значение, такое как -1)
  • добавить "Max" значение enum при наибольшем значении в enum

Вот пример:

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,

Другие вопросы по тегам