2

我正在编写一个小型库,使用它 C++ 中的枚举应该变得更容易。语法类似于:

ENUM_START(MyEnum)
    ENUM_VAL(Val1)
    ENUM_VAL(Val2)
    ...
ENUM_END

此宏创建一个 MyEnum 类,例如允许以下访问:

MyEnum bla=MyEnum::Val1;
for(MyEnum::iterator iter=MyEnum::begin();iter!=MyEnum::end();++iter)
    cout << iter->toString();

以及更多功能,例如将附加数据(例如字符串)存储到枚举值。

宏已经完成并且可以工作,但并不像上面显示的那样容易定义。为此,我需要一种方法来创建带有 ENUM_VAL 宏的初始化函数列表,以便稍后调用。类似于以下 boost::mpl 方法:

typedef mpl::vector<> list__COUNTER__;
#define ENUM_VAL(Name)                                                         \
    ...                                                                        \
    struct Init##Name{void init() {initialization code}};                      \
    typedef mpl::push_back<                                                    \
        list##(__COUNTER-1),                                                   \
        Init##Name                                                             \
      >::type list##__COUNTER__;                                               \

这样 list##(__COUNTER__-1) 最终包含类型 Init##Name ,我最终可以使用 mpl foreach 对所有存储类型调用 init() 。

现在的问题是命名。每个宏实例化我必须使用 __COUNTER__ 两次,这会使计数器增加两次。我已经搜索并发现

  • 命名变量时,C 预处理器不计算 (__COUNTER__-1)
  • 如果不增加它,就无法读取 __COUNTER__ 。

所以我需要另一种方法来收集我以后可以调用的函数列表。

4

2 回答 2

2

您可以使用Boost.Preprocessor,特别是它的序列。这将导致类似于以下的宏用法:

MAKE_ENUM(MyEnum, (Val1)(Val2)(Val3))

使用SEQ_ENUMSEQ_FOR_EACH_I,您可以相对容易地生成代码。

还有一个提议的Boost.Enum可能已经满足您的需求。

于 2012-01-19T19:40:13.920 回答
1

除了模板元编程之外,只有模板引擎可以在预处理器看到代码之前作为脚本运行。 这还有一个额外的好处,就是它只是简单的代码,因此您可以更轻松地调试它

如果有人想改变某些东西,缺点是增加了另一个工具要求。

我以前用过猎豹,结果并不失望。

于 2012-01-19T19:46:59.980 回答