【发布时间】:2012-01-19 19:22:06
【问题描述】:
我正在编写一个小型库,使用它可以让 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__ 就无法读取。
所以我需要另一种方法来收集以后可以调用的函数列表。
【问题讨论】:
-
这种方法的一个缺点是调试器在查看
MyEnum类型的变量时可能不会显示“枚举”名称,这与真正的枚举不同。 -
您可以使用“X 宏”技术获得您想要的行为:drdobbs.com/184401387
标签: c++ c-preprocessor metaprogramming template-meta-programming boost-mpl