3 回答
TA贡献1806条经验 获得超8个赞
当然,天真的解决方案是为执行转换为字符串的每个枚举编写一个函数:
enum OS_type { Linux, Apple, Windows };inline const char* ToString(OS_type v){ switch (v) { case Linux: return "Linux"; case Apple: return "Apple"; case Windows: return "Windows"; default: return "[Unknown OS_type]"; }}
然而,这是一场维护灾难。借助可与C和C ++代码一起使用的Boost.Preprocessor库,您可以轻松利用预处理器并让它为您生成此功能。生成宏如下:
#include <boost/preprocessor.hpp>
#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE(r, data, elem) \
case elem : return BOOST_PP_STRINGIZE(elem);
#define DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators) \
enum name { \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
\
inline const char* ToString(name v) \
{ \
switch (v) \
{ \
BOOST_PP_SEQ_FOR_EACH( \
X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOSTRING_CASE, \
name, \
enumerators \
) \
default: return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \
} \
}
第一个宏(以...开头X_
)在第二个内部使用。第二个宏首先生成枚举,然后生成一个ToString
函数,该函数接受该类型的对象并将枚举器名称作为字符串返回(此实现,出于显而易见的原因,要求枚举器映射到唯一值)。
在C ++中,您可以将该ToString
函数实现为operator<<
重载,但我认为要求显式“ ToString
”将值转换为字符串形式更为清晰。
作为用法示例,您的OS_type
枚举将定义如下:
DEFINE_ENUM_WITH_STRING_CONVERSIONS(OS_type, (Linux)(Apple)(Windows))
虽然宏首先看起来像是很多工作,而OS_type
外观的定义相当陌生,但请记住你必须编写一次宏,然后你可以将它用于每个枚举。您可以添加其他功能(例如,字符串形式到枚举转换)而不会有太多麻烦,它完全解决了维护问题,因为您只需在调用宏时提供一次名称。
然后可以使用枚举,就好像它是正常定义的:
#include <iostream>int main(){ OS_type t = Windows; std::cout << ToString(t) << " " << ToString(Apple) << std::endl;}
从帖子开始,这篇帖子中的代码片段#include <boost/preprocessor.hpp>
可以编译为发布以演示解决方案。
这个特殊的解决方案适用于C ++,因为它使用C ++特定的语法(例如,没有typedef enum
)和函数重载,但是使用C也可以直接使用它。
TA贡献1790条经验 获得超9个赞
这是预处理器块
#ifndef GENERATE_ENUM_STRINGS #define DECL_ENUM_ELEMENT( element ) element #define BEGIN_ENUM( ENUM_NAME ) typedef enum tag##ENUM_NAME #define END_ENUM( ENUM_NAME ) ENUM_NAME; \ char* GetString##ENUM_NAME(enum tag##ENUM_NAME index);#else #define DECL_ENUM_ELEMENT( element ) #element #define BEGIN_ENUM( ENUM_NAME ) char* gs_##ENUM_NAME [] = #define END_ENUM( ENUM_NAME ) ; char* GetString##ENUM_NAME(enum \ tag##ENUM_NAME index){ return gs_##ENUM_NAME [index]; }#endif
枚举定义
BEGIN_ENUM(Os_type){ DECL_ENUM_ELEMENT(winblows), DECL_ENUM_ELEMENT(hackintosh),}
打电话使用
GetStringOs_type(winblows);
- 3 回答
- 0 关注
- 3154 浏览
添加回答
举报