有很多解决方案如何使用 C++ 处理器(例如 this topic)将枚举的文本表示形式获取为字符串。
但是,我想以相反的方向进行转换,以模仿字符串上的开关。
例如 - 给定以下枚举:
typedef enum { RIGHT, LEFT, FORWARD, BACKWARD} direction;
对于小型枚举,可以定义字符串数组并使用枚举值来获取适当的字符串,但这不利于维护。
我想要一些定义函数“direction FromString(char * str)”的宏,如果我有一个字符串“RIGHT”,它会返回 RIGHT。
其他编程语言有很多解决方案,例如 C#或 Java ,所以我不认为这是一种糟糕的做法。
有一个similar question去挖矿,但不使用预处理器。
我当前的解决方案(基于 one of the answers to another question)如下所示:
#include <boost/preprocessor.hpp>
#define X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOENUM(r, data, elem) \
if (!strcmp(s, BOOST_PP_STRINGIZE( elem ))) return elem;
#define DEFINE_ENUM_WITH_STRING_CONVERSIONS(name, enumerators) \
enum name { \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
inline const name FromString(char * s) { \
BOOST_PP_SEQ_FOR_EACH( \
X_DEFINE_ENUM_WITH_STRING_CONVERSIONS_TOENUM, \
name, \
enumerators \
) \
return ERR; \
}
可以通过以下方式使用它:
DEFINE_ENUM_WITH_STRING_CONVERSIONS(direction, (RIGHT)(LEFT)(...)(ERR))
缺点是必须包含 ERR 来处理字符串与任何枚举名称都不匹配的情况。如何避免这种情况?
我在想,也许更优雅的解决方案是使用 Boost Bimap .
最佳答案
你可以试试这个库(免责声明——我是作者):https://github.com/aantron/better-enums
相关方法是_from_string (链接是文档)。如果出现错误,该方法会引发异常。还有另一种方法 returns an option ,类似于 boost::optional
。
如果你想实现自己的版本,this answer中有方法的描述。在堆栈溢出上。该答案中的代码包括 _from_string
的实现。
关于c++ - 使用预处理器从 C++ 中的字符串获取枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31607208/