【问题标题】:Collecting a list of functions that later should be called in macros收集稍后应在宏中调用的函数列表
【发布时间】: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


【解决方案1】:

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

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

使用SEQ_ENUMSEQ_FOR_EACH_I等,就可以比较容易地生成代码了。

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

【讨论】:

  • 序列非常强大。我不能说我很想经常使用宏,但它们通常是原因。
【解决方案2】:

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

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

我之前曾为此使用过Cheetah,结果并不令我失望。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-12
    • 2011-04-18
    • 1970-01-01
    • 2012-04-20
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多