类实现C ++枚举 [英] Class implementation of C++ Enums

查看:107
本文介绍了类实现C ++枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 BitWhistler的回答 http://stackoverflow.com/ a / 31626513/365229 我实现了一个C ++枚举类。希望这有助于寻找这个东西的其他人。



一些操作符重载为方便,现在你可以使用c ++中的枚举作为类的对象。它还支持以下运算符:




  • << ostream

  • >> istream

  • + string concat

  • == 对象和枚举比较

  • ! = 对象和枚举比较

  • = / ul>

    检查答案。

    解决方案

      #define ENUM_MEMBER(MEMBER)\ 
    ,MEMBER

    #define ENUM_FROM_STRING(MEMBER)\
    if(str == #MEMBER)return MEMBER;

    #define ENUM_TO_STRING(MEMBER)\
    case MEMBER:return #MEMBER;

    #define CREATE_ENUM_1(NAME,MACRO,DEFAULT)\
    class NAME {\
    public:\
    枚举E {\
    DEFAULT \
    MACRO(ENUM_MEMBER)\
    }; \
    protected:\
    E _value; \
    public:\
    NAME(){_value = DEFAULT; } \
    NAME(const NAME& copy){_value = copy._value; } \
    NAME(const char ch []):NAME(string(ch)){} \
    NAME(const string& s){_value = fromString } \
    NAME(const E en)\
    {if(!isValid(en))_value = DEFAULT; else _value = en; } \
    \
    NAME& operator =(const NAME& r)\
    {\
    if(this!=& r)\
    _value = r._value; \
    return * this; \
    } \
    \
    NAME& operator =(const NAME :: E& r)\
    {\
    _value = r; \
    return * this; \
    } \
    \
    bool operator ==(const NAME :: E& r)const {return _value == r; } \
    bool operator!=(const NAME :: E& r)const {return _value!= r; } \
    bool operator ==(const NAME& r)const {return _value == r._value; } \
    bool operator!=(const NAME& r)const {return _value!= r._value; } \
    string operator +(const string& r)const {return toString()+ r; } \
    NAME :: E value()const {return _value; } \
    \
    string toString()const {return name(_value); } \
    NAME :: E fromString(const string& str)\
    {_value = parse(str); return _value; } \
    \
    静态向量< NAME> getVector()\
    {\
    static vector< NAME> vec = {DEFAULT MACRO(ENUM_MEMBER)}; \
    return vec; \
    } \
    \
    static E getDefault(){return E :: DEFAULT; } \
    静态字符串名称(const NAME :: E e)\
    {\
    switch(e){\
    MACRO(ENUM_TO_STRING)\
    default:return #DEFAULT; \
    } \
    } \
    \
    static E parse(const string& str)\
    {\
    MACRO ENUM_FROM_STRING)\
    return E :: DEFAULT; \
    } \
    \
    static size_t count()\
    {\
    static E all [] = {DEFAULT MACRO(ENUM_MEMBER)} ; \
    return sizeof(all)/ sizeof(E); \
    } \
    \
    static bool isValid(const string& str)\
    {\
    E e = parse(str); \
    if(e == E :: DEFAULT&& str!= #DEFAULT)\
    return false; \
    return true; \
    } \
    \
    static bool isValid(const int val)\
    {\
    string s = name( )val); \
    if(s == #DEFAULT&& val!= E :: DEFAULT)\
    return false; \
    return true; \
    } \
    }; \
    string operator +(const string& l,const NAME& en); \
    std :: ostream& operator<<(std :: ostream& s,const NAME& en); \
    std :: istream& operator>>(std :: istream& s,NAME& en);

    #define CREATE_ENUM_2(NAME,DEFAULT)\
    CREATE_ENUM_1(NAME,NAME ## _ Members,DEFAULT)

    #define CREATE_ENUM(NAME,DEFAULT)\\ \\
    CREATE_ENUM_2(NAME,DEFAULT)

    在源代码中使用此宏避免链接错误:

      #define CREATE_ENUM_CPP(NAME)\ 
    字符串运算符+ l,const NAME& en){return l + en.toString(); } \
    std :: ostream& operator<<(std :: ostream& s,const NAME& en){s< en.toString(); return s;} \
    std :: istream& operator>>(std :: istream& s,NAME& en){string t; s>> t; en.fromString(t); return s;}

    使用

      #define Animal_Members(ENUM)\ 
    ENUM(DOG)\
    ENUM(CAT)\
    ENUM )\

    CREATE_ENUM(Animal,None)
    //在源代码中:
    CREATE_ENUM_CPP(Animal)

    TEST

      cout< ; Animal :: parse(CAT)<< endl; 
    cout< Animal :: parse(INVALID STRING)<< endl;
    cout< Animal :: name(Animal :: CAT) endl;
    auto vec = Animal :: getVector();
    for(auto it = vec.begin(); it!= vec.end(); ++ it)
    cout< * it< endl;

    Animal cat =CAT,DOG =DOG;
    cout< (cat == DOG):< (cat == DOG)< endl;
    Animal a =CAT;
    string string_concat =VALUE:+ a;
    cout< string_concat<< endl;
    cin>>一个;
    cout< INPUT:<< a<< endl;
    cout< defalut =< Animal(Animal :: getDefault())<< endl;

    动物d(DOG); // string init
    d =COW; // string assignment;
    d = Animal :: CAT; // enum assginment;
    Animal e = d; // copy constructor
    cout<< (e == d):<< (e == d)<< endl; //比较


    According to the answer of BitWhistler http://stackoverflow.com/a/31626513/365229 I've implemented a class for C++ enums. Hope this helps other people who looking for this thing.

    some operators overloaded for convenience and now you can use enums in c++ as an Object of a class. It also supports following operators:

    • << ostream
    • >> istream
    • + string concat
    • == object and enum comparison
    • != object and enum comparison
    • = string and enum assignment

    check the answer.

    解决方案

    #define ENUM_MEMBER(MEMBER)                         \
        , MEMBER
    
    #define ENUM_FROM_STRING(MEMBER)                    \
        if(str == #MEMBER ) return MEMBER;
    
    #define ENUM_TO_STRING(MEMBER)                      \
        case MEMBER: return #MEMBER;
    
    #define CREATE_ENUM_1(NAME,MACRO,DEFAULT)                               \
        class NAME {                                                        \
        public:                                                             \
            enum E {                                                        \
                DEFAULT                                                     \
                MACRO(ENUM_MEMBER)                                          \
            };                                                              \
        protected:                                                          \
            E _value;                                                       \
        public:                                                             \
            NAME() { _value = DEFAULT; }                                    \
            NAME(const NAME& copy) { _value = copy._value; }                \
            NAME(const char ch[]) : NAME(string(ch)) {}                     \
            NAME(const string& s) { _value = fromString(s); }               \
            NAME(const E en)                                                \
            { if(!isValid(en)) _value = DEFAULT; else _value = en; }        \
                                                                            \
            NAME& operator=(const NAME& r)                                  \
            {                                                               \
                if(this != &r)                                              \
                    _value = r._value;                                      \
                return *this;                                               \
            }                                                               \
                                                                            \
            NAME& operator=(const NAME::E& r)                               \
            {                                                               \
                _value = r;                                                 \
                return *this;                                               \
            }                                                               \
                                                                            \
            bool operator==(const NAME::E& r) const { return _value == r; }          \
            bool operator!=(const NAME::E& r) const { return _value != r; }          \
            bool operator==(const NAME& r) const { return _value == r._value; }      \
            bool operator!=(const NAME& r) const { return _value != r._value; }      \
            string operator+(const string& r) const { return toString() + r; }       \
            NAME::E value() const { return _value; }                                 \
                                                                                         \
            string toString() const { return name(_value); }                             \
            NAME::E fromString(const string& str)                                        \
                { _value = parse(str); return _value; }                                  \
                                                                                         \
            static vector<NAME> getVector()                                              \
            {                                                                            \
                static vector<NAME> vec = { DEFAULT MACRO(ENUM_MEMBER) };                \
                return vec;                                                              \
            }                                                                            \
                                                                                         \
            static E getDefault() { return E::DEFAULT; }                                 \
            static string name(const NAME::E e)                             \
            {                                                               \
                switch( e ) {                                               \
                    MACRO(ENUM_TO_STRING)                                   \
                    default: return #DEFAULT;                               \
                }                                                           \
            }                                                               \
                                                                            \
            static E parse(const string& str)                               \
            {                                                               \
                MACRO(ENUM_FROM_STRING)                                     \
                return E::DEFAULT;                                          \
            }                                                               \
                                                                            \
            static size_t count()                                           \
            {                                                               \
                static E all[] = { DEFAULT MACRO(ENUM_MEMBER) };            \
                return sizeof(all) / sizeof(E);                             \
            }                                                               \
                                                                            \
            static bool isValid(const string& str)                          \
            {                                                               \
                E e = parse(str);                                           \
                if(e == E::DEFAULT && str != #DEFAULT)                      \
                    return false;                                           \
                return true;                                                \
            }                                                               \
                                                                            \
            static bool isValid(const int val)                              \
            {                                                               \
                string s = name((NAME::E)val);                              \
                if(s == #DEFAULT && val != E::DEFAULT)                      \
                    return false;                                           \
                return true;                                                \
            }                                                               \
        };\
    string operator+(const string& l, const NAME& en);  \
    std::ostream& operator<<(std::ostream& s, const NAME& en); \
    std::istream& operator>>(std::istream& s, NAME& en);
    
    #define CREATE_ENUM_2(NAME,DEFAULT) \
        CREATE_ENUM_1(NAME,NAME##_Members,DEFAULT)
    
    #define CREATE_ENUM(NAME,DEFAULT) \
        CREATE_ENUM_2(NAME,DEFAULT)
    

    use this macro in source code to avoid link error:

    #define CREATE_ENUM_CPP(NAME) \
    string operator+(const string& l, const NAME& en) { return l + en.toString(); }  \
    std::ostream& operator<<(std::ostream& s, const NAME& en) { s << en.toString(); return s;} \
    std::istream& operator>>(std::istream& s, NAME& en) { string t; s >> t; en.fromString(t); return s;}
    

    Usage

    #define Animal_Members(ENUM) \
        ENUM(DOG) \
        ENUM(CAT) \
        ENUM(COW) \
    
    CREATE_ENUM(Animal,None)
    // in source code:
    CREATE_ENUM_CPP(Animal)
    

    TEST

    cout << Animal::parse("CAT") << endl;
    cout << Animal::parse("INVALID STRING") << endl;
    cout << Animal::name(Animal::CAT) << endl;
    auto vec = Animal::getVector();
    for(auto it = vec.begin(); it != vec.end() ; ++it)
        cout << *it << endl;
    
    Animal cat = "CAT", DOG = "DOG";
    cout << "(cat == DOG): " << (cat == DOG) << endl;
    Animal a = "CAT";
    string string_concat = "VALUE: " + a;
    cout << string_concat << endl;
    cin >> a;
    cout << "INPUT: " << a << endl;
    cout << "defalut=" << Animal(Animal::getDefault()) << endl;
    
    Animal d("DOG"); // string init
    d = "COW"; // string assignment;
    d = Animal::CAT; // enum assginment;
    Animal e = d; //copy constructor
    cout << "(e == d): " << (e == d) << endl; // compare
    

    这篇关于类实现C ++枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆