最近在学习有限状态机的时候,遇到了一个问题,如何获取枚举类型的枚举值对应的字符串?第一反应就是就是创建一个字符串的映射数组。这样做确实能够达到效果,但是始终觉得不太好看。最后终于在StackOverFlow上找到了一个类似的问题,下面我介绍一下最佳答案,代码如下:

代码段一: 作为头文件引入公共宏的部分

  1. /// enumFactory.h
  2. // expansion macro for enum value definition
  3. #define ENUM_VALUE(name,assign) name assign,
  4. // expansion macro for enum to string conversion
  5. #define ENUM_CASE(name,assign) case name: return #name;
  6. // expansion macro for string to enum conversion
  7. #define ENUM_STRCMP(name,assign) if (!strcmp(str,#name)) return name;
  8. /// declare the access function and define enum values
  9. #define DECLARE_ENUM(EnumType,ENUM_DEF) \
  10. enum EnumType { \
  11. ENUM_DEF(ENUM_VALUE) \
  12. }; \
  13. const char *GetString(EnumType dummy); \
  14. EnumType Get##EnumType##Value(const char *string); \
  15. /// define the access function names
  16. #define DEFINE_ENUM(EnumType,ENUM_DEF) \
  17. const char *GetString(EnumType value) \
  18. { \
  19. switch(value) \
  20. { \
  21. ENUM_DEF(ENUM_CASE) \
  22. default: return ""; /* handle input error */ \
  23. } \
  24. } \
  25. EnumType Get##EnumType##Value(const char *str) \
  26. { \
  27. ENUM_DEF(ENUM_STRCMP) \
  28. return (EnumType)0; /* handle input error */ \
  29. } \

代码段二: 在使用处的定义

  1. /// 放在引入的文件中
  2. #define SOME_ENUM(XX) \
  3. XX(FirstValue,) \
  4. XX(SecondValue,) \
  5. XX(SomeOtherValue,=50) \
  6. XX(OneMoreValue,=100) \
  7. DECLARE_ENUM(SomeEnum, SOME_ENUM)
  8. DEFINE_ENUM(SomeEnum, SOME_ENUM)

我们在需要使用的文件中引入enumFactory.h文件,并在文件中添加对应的代码段二,就能够在代码中通过枚举值获取对应的字符串或者通过字符串获取对应的枚举值。
下面我们来看一下这段宏是如何实现的:

首先,假定我们希望定义一个宏enum SomeEnum{FirstValue, SecondValue, SomeOtherValue=50, OneMoreValue=100}
大家会发现这个和上面的#define SOME_ENUM(XX)的内容很相似。实际上我们把SOME_ENUMENUM_VALUE这两个宏结合起来SOME_ENUM(ENUM_VALUE),这个时候#define SOME_ENUM(XX)就展开成了{FirstValue, SecondValue, SomeOtherValue=50, OneMoreValue=100}再结合DECLARE_ENUM的定义我们就得到了我们最开始想定义的宏了。DEFINE_ENUM就是定义了两个函数,一个是GetString(),另一个是GetSomeEnumValue()。这两个函数实现了通过枚举值获取字符串和通过字符串获取枚举值的功能。