2

I have a C++ enum of error codes (30 of them) and there is a function that returns an error code in case of a problem. Is there a way to parse the enum so as to check which of the error codes has been returned and provide the interpretation? I know switch statement could be an option here but was looking for something different to avoid writing lots of switch statements.

Peter M
  • 7,309
  • 3
  • 50
  • 91
Amani
  • 16,245
  • 29
  • 103
  • 153

3 Answers3

2

No, it is not possible: names of enum constants are compile-time artifacts, they are not available at runtime*.

You can make a map<string,MyEnumType> and populate it with names of enums and their values. You can use "stringize macros" to avoid typing the same value multiple times:

#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 obtain this information through a symbol table provided by the compiler.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

What you can do is providing a map (as I mentioned in my comment):

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
  • 13
  • 116
  • 190
1

In complement of dashblinkenlight's answer, you could play X-macro C&C++ preprocessor tricks like:

 // 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")

then you would first define the enum using:

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

and later define the printing e.g. with

 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
 }

Or you could play similar tricks to provide the equivalent of πάντα ῥεῖ 's answer

See also this answer about creative uses of multiple #include-s of the same file.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547