Creating a string list and an enum list from a C++ macro

后端 未结 8 1278
误落风尘
误落风尘 2020-12-14 08:26

In order to make my code shorter and easier to change I want to replace something like

enum{ E_AAA, E_BBB, E_CCC };
static const char *strings{\"AAA\", \"BBB         


        
相关标签:
8条回答
  • 2020-12-14 09:09

    Here is my solution:

    #define FRUITS(fruit) \
      fruit(Apple)        \
      fruit(Orange)       \
      fruit(Banana)       
    
    #define CREATE_ENUM(name) \
      F_##name,
    
    #define CREATE_STRINGS(name) \
      #name,
    

    The trick is that 'fruit' is an argument of the macro 'FRUITS' and will be replaced by what ever you pass to. For example:

    FRUITS(CREATE_ENUM)
    

    will expand to this:

    F_Apple, F_Orange, F_Banana, 
    

    Lets create the enum and the string array:

    enum fruit {
      FRUITS(CREATE_ENUM)
    };
    
    const char* fruit_names[] = {
      FRUITS(CREATE_STRINGS)
    };
    
    0 讨论(0)
  • 2020-12-14 09:10

    Here a solution I learned a few days ago. The simplified version that attends your question is:

    #define ENUM_MACRO(name, v1, v2, v3, v4, v5, v6, v7)\
        enum name { v1, v2, v3, v4, v5, v6, v7};\
        const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};
    
    ENUM_MACRO(Week, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
    

    But you can have an improved version, with a function call, like this:

    #define ENUM_MACRO(name, v1, v2, v3, v4, v5, v6, v7)\
        enum name { v1, v2, v3, v4, v5, v6, v7};\
        const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};\
        const char *name##ToString(value) { return name##Strings[value]; }
    
    ENUM_MACRO(Week, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
    

    This will grow to be:

      enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat}; 
      const char *WeekStrings[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; 
      const char *WeekToString(value) { return WeekStrings[value]; };
    

    You can even use an offset for the first element, like this one:

    #define ENUM_MACRO(name, offset, v1, v2, v3, v4, v5, v6, v7)\
        enum name { v1 =  offset, v2, v3, v4, v5, v6, v7};\
        const char *name##Strings[] = { #v1, #v2, #v3, #v4, #v5, #v6, #v7};\
        const char *name##ToString(value) { return name##Strings[value - offset ]; }
    
    ENUM_MACRO(Week, 1, Sun, Mon, Tue, Wed, Thu, Fri, Sat);
    

    I hope this helps.

    Take care, Beco

    Reference:

    Print the month question, by Kush, answer by Danny Varod

    0 讨论(0)
提交回复
热议问题