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

后端 未结 8 1314
误落风尘
误落风尘 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:07

    You can do it with a bit of macro magic:

    #define FRUITS \
        etype(Unknown), \
        etype(Apple),   \
        etype(Orange),  \
        etype(Banana),  \
        etype(Apricot), \
        etype(Mango)
    
    #define etype(x) F_##x
    
    typedef enum { FRUITS } Fruit;
    
    #undef etype
    #define etype(x) #x
    
    static const char *strFruit[] = { FRUITS };
    

    Here is a test program:

    #include 
    #include 
    #include 
    
    #define FRUITS \
        etype(Unknown), \
        etype(Apple),   \
        etype(Orange),  \
        etype(Banana),  \
        etype(Apricot), \
        etype(Mango)
    
    #define etype(x) F_##x
    
    typedef enum { FRUITS } Fruit;
    
    #undef etype
    #define etype(x) #x
    
    static const char *strFruit[] = { FRUITS };
    
    const char *enum2str (Fruit f)
    {
        return strFruit[static_cast(f)];
    }
    
    Fruit str2enum (const char *f)
    {
        const int n = sizeof(strFruit) / sizeof(strFruit[0]);
        for (int i = 0; i < n; ++i)
        {
            if (strcmp(strFruit[i], f) == 0)
                return (Fruit) i;
        }
        return F_Unknown;
    }
    
    int main (int argc, char *argv[])
    {
        std::cout << "I like " << enum2str(F_Mango) << std::endl;
        std::cout << "I do not like " << enum2str(F_Banana) << std::endl;
        std::vector v;
        v.push_back("Apple");
        v.push_back("Mango");
        v.push_back("Tomato");
        for (int i = 0; i < v.size(); ++i)
        {
            const Fruit f = str2enum(v[i]);
            if (f == F_Unknown)
                std::cout << "Is " << v[i] << " a fruit?" << std::endl;
            else
                std::cout << v[i] << " is a fruit" << std::endl;
        }
        return 0;
    }
    

    It outputs:

    I like Mango
    I do not like Banana
    Apple is a fruit
    Mango is a fruit
    Is Tomato a fruit?
    

提交回复
热议问题