C++枚举与字符串转换工具类
最近需要一个能够在字符串和枚举值之间互相转换的功能,因为C++没有对枚举值进行遍历、反射之类的操作,不像Java那样可以轻松搞定。网上找到一些代码感觉用起来有点不爽,于是研究一番后,写了一个工具类。
如果要转换的字符串和枚举名完全一样,请直接使用超赞的 magic_enum。
闲话不多说,直接上代码:
template <typename T>
class EnumHelper {
private:
std::map<T, std::string> _mapEnum2String;
std::map<std::string, T> _mapString2Enum;
T _defaultValue;
private:
static std::map<std::string, T> genString2EnumMap(std::map<T, std::string> enum2StringMap)
{
std::map<std::string, T> result;
for (const auto& item : enum2StringMap) {
result.emplace(std::make_pair(item.second, item.first));
}
return result;
};
public:
// constructor with initial enum-string map and a default enum value
EnumHelper(const std::map<T, std::string>&& origin, const T defaultValue)
{
_mapEnum2String = std::move(origin);
_mapString2Enum = genString2EnumMap(_mapEnum2String);
_defaultValue = defaultValue;
}
T toEnum(const std::string& str)
{
if (str.empty()) {
return _defaultValue;
}
auto find = _mapString2Enum.find(str);
if (find == _mapString2Enum.end()) {
LOG(ERROR) << "Unrecognized string \"" << str << "\" for enum: " << typeid(T).name();
return _defaultValue;
} else {
return find->second;
}
}
// get enum from string, if not matched, return specified value
T toEnum(const std::string& str, const T defaultValue)
{
auto find = _mapString2Enum.find(str);
if (find == _mapString2Enum.end()) {
LOG(ERROR) << "Unrecognized string \"" << str << "\" for enum: " << typeid(T).name();
return defaultValue;
} else {
return find->second;
}
}
std::string toString(const T& enumValue)
{
return _mapEnum2String.at(enumValue);
}
};
逻辑很简单,就是基于模板创建两个字符串和枚举值映射关系的map,然后就可以用内置的函数实现转换了。构造函数的参数有两个,一个是字符串与枚举的映射数组,另一个是无法识别字符串时的缺省枚举值。下面是针对一个枚举的定义实例:
static EnumHelper<DataStatus> DataStatusHelper(
{ {DataStatus_Created, "created"},
{DataStatus_Active, "active"},
{DataStatus_Inactive, "inactive"},
{DataStatus_Deleted, "deleted"} },
DataStatus_Deleted);
上面的代码申明了一个DataStatusHelper的转换类实例(注意,是对象实例,不是类),所以,你应该在合适的地方把它申明成全局变量,然后在需要进行转换的地方,用下面的方法调用:
// 字符串转枚举
auto status = DataStatusHelper.toEnum("created");
// 枚举转字符串
std::string str = DataStatusHelper.toString(DataStatus::DataStatus_Created);
这是目前为止我所知道的使用者最节省代码的写法了,觉得好,点个赞哦!