How to Get enum item name from its value

后端 未结 10 955
天涯浪人
天涯浪人 2020-12-08 09:56

I declared a enum type as this,

enum WeekEnum
{
Mon = 0;
Tue = 1;
Wed = 2;
Thu = 3;
Fri = 4;
Sat = 5;
Sun = 6;
};

How can I get the item na

相关标签:
10条回答
  • 2020-12-08 10:11

    An enumeration is something of an inverse-array. What I believe you want is this:

    const char * Week[] = { "", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };  // The blank string at the beginning is so that Sunday is 1 instead of 0.
    cout << "Today is " << Week[2] << ", enjoy!";  // Or whatever you'de like to do with it.
    
    0 讨论(0)
  • 2020-12-08 10:13

    No, you have no way to get the "name" from the value in C++ because all the symbols are discarded during compilation.

    You may need this way X Macros

    0 讨论(0)
  • 2020-12-08 10:13

    How can I get the item name "Mon, Tue, etc" when I already have the item value "0, 1, etc."

    On some older C code (quite some time ago), I found code analogous to:

    std::string weekEnumToStr(int n)
    {
       std::string s("unknown");
       switch (n)
       {
       case 0: { s = "Mon"; } break;
       case 1: { s = "Tue"; } break;
       case 2: { s = "Wed"; } break;
       case 3: { s = "Thu"; } break;
       case 4: { s = "Fri"; } break;
       case 5: { s = "Sat"; } break;
       case 6: { s = "Sun"; } break;
       }
       return s;
    }
    

    Con: This establishes a "pathological dependency" between the enumeration values and the function... meaning if you change the enum you must change the function to match. I suppose this is true even for a std::map.

    I vaguely remember we found a utility to generate the function code from the enum code. The enum table length had grown to several hundred ... and at some point it is maybe a sound choice to write code to write code.


    Note -

    in an embedded system enhancement effort, my team replaced many tables (100+?) of null-terminated-strings used to map enum int values to their text strings.

    The problem with the tables was that a value out of range was often not noticed because many of these tables were gathered into one region of code / memory, such that a value out-of-range reached past the named table end(s) and returned a null-terminated-string from some subsequent table.

    Using the function-with-switch statement also allowed us to add an assert in the default clause of the switch. The asserts found several more coding errors during test, and our asserts were tied into a static-ram-system-log our field techs could search.

    0 讨论(0)
  • 2020-12-08 10:17

    If you know the actual enum labels correlated to their values, you can use containers and C++17's std::string_view to quickly access values and their string representations with the [ ] operator while tracking it yourself. std::string_view will only allocate memory when created. They can also be designated with static constexpr if you want them available at run-time for more performance savings. This little console app should be fairly fast.

    #include <iostream>
    #include <string_view>
    #include <tuple>    
    int main() {
        enum class Weekdays { //default behavior starts at 0 and iterates by 1 per entry
            Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday
        };
    
        static constexpr std::string_view Monday    = "Monday";
        static constexpr std::string_view Tuesday   = "Tuesday";
        static constexpr std::string_view Wednesday = "Wednesday";
        static constexpr std::string_view Thursday  = "Thursday";
        static constexpr std::string_view Friday    = "Friday";
        static constexpr std::string_view Saturday  = "Saturday";
        static constexpr std::string_view Sunday    = "Sunday";
        static constexpr std::string_view opener    = "enum[";
        static constexpr std::string_view closer    = "] is ";
        static constexpr std::string_view semi      = ":";
    
        std::pair<Weekdays, std::string_view> Weekdays_List[] = {
            std::make_pair(Weekdays::Monday,    Monday),
            std::make_pair(Weekdays::Tuesday,   Tuesday),
            std::make_pair(Weekdays::Wednesday, Wednesday),
            std::make_pair(Weekdays::Thursday,  Thursday),
            std::make_pair(Weekdays::Friday,    Friday),
            std::make_pair(Weekdays::Saturday,  Saturday),
            std::make_pair(Weekdays::Sunday,    Sunday)
        };
    
        for (int i=0;i<sizeof(Weekdays_List)/sizeof(Weekdays_List[0]);i++) {
            std::cout<<opener<<i<<closer<<Weekdays_List[(int)i].second<<semi\
            <<(int)Weekdays_List[(int)i].first<<std::endl;
        }    
        return 0;
    }
    

    Output:

    enum[0] is Monday:0
    enum[1] is Tuesday:1
    enum[2] is Wednesday:2
    enum[3] is Thursday:3
    enum[4] is Friday:4
    enum[5] is Saturday:5
    enum[6] is Sunday:6
    
    0 讨论(0)
  • 2020-12-08 10:21

    The solution I prefer is to mix arrays and ostream like this:

    std::ostream& operator<<(std::ostream& lhs, WeekEnum e) {
        static const std::array<std::string, 7> WEEK_STRINGS = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
    
        return os << WEEK_STRINGS[statuc_cast<WeekEnum>(e)]
    }
    
    cout << "Today is " << WeekEnum::Monday;
    

    I also suggest to use enum class instead of Enum

    0 讨论(0)
  • 2020-12-08 10:26

    Here is another neat trick to define enum using X Macro:

    #include <iostream>
    
    #define WEEK_DAYS \
    X(MON, "Monday", true) \
    X(TUE, "Tuesday", true) \
    X(WED, "Wednesday", true) \
    X(THU, "Thursday", true) \
    X(FRI, "Friday", true) \
    X(SAT, "Saturday", false) \
    X(SUN, "Sunday", false)
    
    #define X(day, name, workday) day,
    enum WeekDay : size_t
    {
        WEEK_DAYS
    };
    #undef X
    
    #define X(day, name, workday) name,
    char const *weekday_name[] =
    {
        WEEK_DAYS
    };
    #undef X
    
    #define X(day, name, workday) workday,
    bool weekday_workday[]
    {
        WEEK_DAYS
    };
    #undef X
    
    int main()
    {
        std::cout << "Enum value: " << WeekDay::THU << std::endl;
        std::cout << "Name string: " << weekday_name[WeekDay::THU] << std::endl;
        std::cout << std::boolalpha << "Work day: " << weekday_workday[WeekDay::THU] << std::endl;
    
        WeekDay wd = SUN;
        std::cout << "Enum value: " << wd << std::endl;
        std::cout << "Name string: " << weekday_name[wd] << std::endl;
        std::cout << std::boolalpha << "Work day: " << weekday_workday[wd] << std::endl;
    
        return 0;
    }
    

    Live Demo: https://ideone.com/bPAVTM

    Outputs:

    Enum value: 3
    Name string: Thursday
    Work day: true
    Enum value: 6
    Name string: Sunday
    Work day: false
    
    0 讨论(0)
提交回复
热议问题