如前所述,没有标准的方法可以做到这一点。但是通过一点预处理器魔法(类似于 AlejoHausner 的第二个贡献)和一些模板魔法,它可以相当优雅。
包含此代码一次:
#include <string>
#include <algorithm>
#define ENUM_VALS( name ) name,
#define ENUM_STRINGS( name ) # name,
/** Template function to return the enum value for a given string
* Note: assumes enums are all upper or all lowercase,
* that they are contiguous/default-ordered,
* and that the first value is the default
* @tparam ENUM type of the enum to retrieve
* @tparam ENUMSIZE number of elements in the enum (implicit; need not be passed in)
* @param valStr string version of enum value to convert; may be any capitalization (capitalization may be modified)
* @param enumStrs array of strings corresponding to enum values, assumed to all be in lower/upper case depending upon
* enumsUpper
* @param enumsUpper true if the enum values are in all uppercase, false if in all lowercase (mixed case not supported)
* @return enum value corresponding to valStr, or the first enum value if not found
*/
template <typename ENUM, size_t ENUMSIZE>
static inline ENUM fromString(std::string &valStr, const char *(&enumStrs)[ENUMSIZE], bool enumsUpper = true) {
ENUM e = static_cast< ENUM >(0); // by default, first value
// convert valStr to lower/upper-case
std::transform(valStr.begin(), valStr.end(), valStr.begin(), enumsUpper ? ::toupper : ::tolower);
for (size_t i = 0; i< ENUMSIZE; i++) {
if (valStr == std::string(enumStrs[i])) {
e = static_cast< ENUM >(i);
break;
}
}
return e;
}
然后像这样定义每个枚举:
//! Define ColorType enum with array for converting to/from strings
#define ColorTypes(ENUM) \
ENUM(BLACK) \
ENUM(RED) \
ENUM(GREEN) \
ENUM(BLUE)
enum ColorType {
ColorTypes(ENUM_VALS)
};
static const char* colorTypeNames[] = {
ColorTypes(ENUM_STRINGS)
};
您只需枚举枚举值一次,定义它的代码相当紧凑和直观。
值必须以默认方式编号(即,0、1、2、...)。 fromString() 的代码假定枚举值全部为大写或全部小写(用于从字符串转换),默认值是第一个,但您当然可以更改这些事情的处理方式。
以下是获取字符串值的方法:
ColorType c = ColorType::BLUE;
std::cout << colorTypeNames[c]; // BLUE
这是从字符串值设置枚举的方法:
ColorType c2 = fromString<ColorType>("Green", colorTypeNames); // == ColorType::GREEN