enum和string相互转换
- 简介
- 满足的需求
- code
- 使用方法
- 可优化点
- 参考链接
简介
原理还是很朴素的方法,只是用宏省略了重复代码,降低维护难度;
// enum to string
std::string enum2Str(Color c)
{
switch(c){
case RED: return "RED";
case ORANGE: return "ORANGE";
......
default: return "Unknown"
}
}
// string to enum
Color enumStr2Enum(const char* enumStr)
{
if (0 == strcmp(enumStr, "RED")) return T::RED;
......
if (0 == strcmp(enumStr, "Unknown")) return T::Unknown;
}
满足的需求
- 更新枚举时不用修改转换相关的接口(enum2Str, str2Enum…);
- 在不同的库使用时只需包含头文件;
- enum能转换成字符串类型,字符串也能转成enum,当然字符串也能转换成enumValue;
code
只有头文件
// foo.h
#include<type_traits>
#ifndef COLOR_H
#define COLOR_H
#define DEF_ENUMS \
X(RED, 1) \
X(ORANGE, 2) \
X(YELLOW, 3) \
X(GREEN, 4) \
X(CYAN, 5) \
X(BLUE, 6) \
X(Unknown, UCHAR_MAX)
enum class Color : uint8_t {
#define X(name, value) name = value,
DEF_ENUMS
#undef X
};
template <typename T>
concept enumType = std::is_enum<T>::value;
/// enum to string
template <enumType T>
std::string enum2Str(T e)
{
switch (e) {
#define X(name, value) \
case T::name: \
return #name;
DEF_ENUMS
#undef X
default:
return "Unknown";
}
}
/// string to enum
template <enumType T>
T enumStr2Enum(const char* enumStr)
{
#define X(name, value) \
if (0 == strcmp(enumStr, #name)) \
return T::name;
DEF_ENUMS
#undef X
return T::Unknown;
}
template <typename enumType>
using enumValue_t = std::underlying_type_t<enumType>;
/** string to enum value
* @brief if enumStr not exist, return "Unknown"
*/
template <enumType T>
enumValue_t<T> enumStr2Value(const char* enumStr)
{
#define X(name, value) \
if (0 == strcmp(enumStr, #name)) \
return value;
DEF_ENUMS
#undef X
return static_cast<enumValue_t<T>>(T::Unknown);
}
#endif /* COLOR_H */
使用方法
#include <iostream>
#include "foo.h"
int main(){
Color color{Color::GREEN};
printf("enum2Str(color): %s\n", enum2Str(color).c_str());
printf("enumStr2Value<Color>: %d\n", enumStr2Value<Color>("GREEN"));
printf("enumStr2Enum<Color>: %d\n",enumStr2Enum<Color>("GREEN"));
return 0;
}
可优化点
头文件可能看着比较难懂,不知开放出来的接口是哪些;
感觉可以把宏的实现改到cpp里,但得注意多个文件使用时的坑
函数定义写在头文件中可能导致的多重定义错误(multiple definition)
C++模板类/函数,将头文件与源文件分离
参考链接
The X Macro - Digital Mars
X-Macros