了解DEFER和OBSTRUCT宏

时间:2015-04-30 08:19:45

标签: c++ c++11 macros c-preprocessor

我创建了small macro metaprogramming library,它实现了基本的有用结构,例如REPEAT(times, x)IF(value, true, false),元组等。

我的大多数实现都是基于其可变参数计数或通过计数器来重载宏:

// Example:
#define REPEAT_0(x) 
#define REPEAT_1(x) x REPEAT_0(x) 
#define REPEAT_2(x) x REPEAT_1(x)
#define REPEAT_3(x) x REPEAT_2(x)
// ...
// (these defines are generated using an external script)
// ...

#define REPEAT(count, x) CAT(REPEAT_, count)(x)

这很好用,但我最近遇到了an extremely interesting implementation of macro recursion by Paul Fultz

直到deferred expression部分,我才能理解他的文章。

但是,我在理解正确使用DEFEROBSTRUCT方面遇到了很多麻烦。

Paul实现了一个非常优雅的REPEAT版本,它不需要脚本生成的定义,如下所示:

#define EAT(...)
#define EXPAND(...) __VA_ARGS__
#define WHEN(c) IF(c)(EXPAND, EAT)

#define REPEAT(count, macro, ...) \
    WHEN(count) \
    ( \
        OBSTRUCT(REPEAT_INDIRECT) () \
        ( \
            DEC(count), macro, __VA_ARGS__ \
        ) \
        OBSTRUCT(macro) \
        ( \
            DEC(count), __VA_ARGS__ \
        ) \
    )
#define REPEAT_INDIRECT() REPEAT

//An example of using this macro
#define M(i, _) i
EVAL(REPEAT(8, M, ~)) // 0 1 2 3 4 5 6 7

DEFEROBSTRUCT和其他实用程序就是这样实现的:

#define EMPTY()
#define DEFER(id) id EMPTY()
#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
#define EXPAND(...) __VA_ARGS__

#define A() 123
A() // Expands to 123
DEFER(A)() // Expands to A () because it requires one more scan to fully expand
EXPAND(DEFER(A)()) // Expands to 123, because the EXPAND macro forces another scan
  • 当预处理器扩展宏时,结果将“绘制”直到下一次扫描 - 除非发生其他扫描,否则它不会递归扩展。 这是正确的吗?

  • EXPAND(...)会强制进行额外扫描吗?如果是这样,此扫描是否允许宏递归扩展? EXPAND(...)DEFER(id)之间有什么区别?

    • DEFER强制进行两次额外扫描吗?
  • OBSTRUCT(...)宏怎么样?是否会强制两次额外扫描?

  • 现在 - 为什么在OBSTRUCT的递归实现中需要REPEAT?为什么DEFEREXPAND不在此处工作?

0 个答案:

没有答案