C ++枚举类的实现 [英] Class implementation of C++ Enums
本文介绍了C ++枚举类的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
根据 BitWhistler的答案
https://stackoverflow.com/ a / 31626513/365229我已经实现了一个C ++枚举类。希望这有助于寻找这个东西的其他人。
According to the answer of BitWhistler
https://stackoverflow.com/a/31626513/365229 I've implemented a class for C++ enums. Hope this helps other people who looking for this thing.
为方便起见,一些运算符重载,现在您可以使用c ++中的枚举作为类的对象。它还支持以下运算符:
some operators overloaded for convenience and now you can use enums in c++ as an Object of a class. It also supports following operators:
-
-
>>
istream -
+
字符串连接 -
==
对象和枚举比较 -
! =
对象和枚举比较 -
=
字符串和枚举分配
<<
ostream>>
istream+
string concat==
object and enum comparison!=
object and enum comparison=
string and enum assignment
检查答案。
推荐答案
#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)
在源代码中使用此宏避免链接错误:
#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;}
用法
#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屋!
查看全文