2014-12-13 3 views
2

У меня есть C++ перечисление кодов ошибок (30 из них), и есть функция, которая возвращает код ошибки в случае возникновения проблемы. Есть ли способ проанализировать перечисление, чтобы проверить, какой из кодов ошибок был возвращен, и предоставить интерпретацию? Я знаю, что оператор switch может быть вариантом здесь, но искал что-то другое, чтобы избежать написания множества операторов switch.Как я могу проанализировать перечисление в C++?

+0

Преобразование перечислений в текст и текст в перечисления является одним из немногих законных применений макросов препроцессора. –

+0

Единственное решение, о котором я знаю, это создать карту, содержащую значения перечисления в виде ключей и соответствующие строковые представления как значения. –

ответ

2

Нет, это невозможно: имена констант перечисления являются артефактами времени компиляции, они недоступны во время выполнения *.

Вы можете сделать map<string,MyEnumType> и заполнить его именами перечислений и их значениями. Вы можете использовать «stringize макросы», чтобы не вводить и то же значение несколько раз:

#include <iostream> 
#include <string> 
#include <map> 
using namespace std; 

#define ADD_ENUM_TO_MAP(m,x) m[#x]=x 

enum MyEnumType { 
    quick, brown, fox, jumps, over, the, lazy, dog 
}; 

int main() { 
    map<string,MyEnumType> nameToEnum; 
    ADD_ENUM_TO_MAP(nameToEnum, quick); 
    ADD_ENUM_TO_MAP(nameToEnum, brown); 
    ADD_ENUM_TO_MAP(nameToEnum, fox); 
    ADD_ENUM_TO_MAP(nameToEnum, jumps); 
    ADD_ENUM_TO_MAP(nameToEnum, over); 
    ADD_ENUM_TO_MAP(nameToEnum, the); 
    ADD_ENUM_TO_MAP(nameToEnum, lazy); 
    ADD_ENUM_TO_MAP(nameToEnum, dog); 
    cout << nameToEnum["fox"] << endl; 
    return 0; 
} 

Demo.

* Debuggers получить эту информацию через таблицу символов, представленной компилятором.

1

Что вы можете сделать, это предоставление карты (как я уже говорил в мой комментарий):

enum ErrorCodes { 
    OK , 
    ERR_FILE_OPEN , 
    ERR_MISSING_INPUT , 
    // ... 
} 

std::map<ErrorCodes,std::string> codeTranslationMap { 
    { OK, "OK" } 
    { ERR_FILE_OPEN , "File open failed." } 
    { ERR_MISSING_INPUT , "Missing input." } 
    // ... 
}; 
1

В дополнение dashblinkenlight's answer, вы могли бы играть X-macro C & C++ preprocessor трюки, как:

// your list of enumerators applied to a preprocessor macro: 
#define ENUM_LIST(P) \ 
    P(ERR_NONE,"no errors") \ 
    P(ERR_FILE_OPEN,"file open") \ 
    P(MISSING_INPUT,"missing input") 

, то вы должны сначала определить перечисление, используя:

#define ENUM_DEFINE(Nam,Str) Nam, 
enum error_en { 
    ENUM_LIST(ENUM_DEFINE) 
}; 
#undef ENUM_DEFINE 

, а затем определить печать, например. с

void out(enum error_en e) { 
    switch(e) { 
#define ENUM_OUT(Nam,Str) case Nam: cout << Str; break; 
ENUM_LIST(ENUM_OUT) 
#undef ENUM_OUT 
    } // end switch 
} 

Или вы можете играть аналогичные трюки, чтобы обеспечить эквивалент πάντα ῥεῖ 's answer

this answer См также о творческом использовании нескольких #include -s одного и тот же файла.

Смежные вопросы