c++ - 使用预处理器从 C++ 中的字符串获取枚举

标签 c++ enums c-preprocessor

有很多解决方案如何使用 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/

相关文章:

c++ - 不使用任何外部库时,是否存在 LNK2001 Unresolved external symbol 错误的可能/常见原因?

c++ - 如何在 QtQuick2Con​​trolsApplicationViewer 上绑定(bind) QML/C++ 类

python - 解决 enum34 元类冲突?

c++ - 多态枚举

clojure - 枚举和Clojure

c - 如何在 C 中解析链接的宏?

c++ - 使用 push_back 和 getline 时如何减少临时对象?

c++ - 一个带有 vector 数据成员的类

c - 枚举宏的效用

c - 为什么这个 C 预处理器代码不起作用?