безошибочное преобразование строки в перечисляемый класс - PullRequest
0 голосов
/ 19 февраля 2019

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

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

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

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, которая охватывает все значения перечисления

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

Так как же я могу подойти к этой проблеме, не пропуская недопустимое перечисление во время выполнения ?

1 Ответ

0 голосов
/ 07 марта 2019

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

  • полагаться на тот факт, что последующим значениям перечисления неявно присваивается значение предыдущего значения перечисления + 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.

...