用__VA_OPT__
编写递归宏合法吗?
GCC和Clang似乎没有递归地替换,但我不确定这是否有意(因为__VA_OPT__
支持是最近的)。
C++规范(第19.3.1/3节:
__VA_OPT__
): 否则,替换由内容扩展结果作为当前类似于函数的宏的替换列表,然后再重新扫描和进一步替换。
上面突出显示的部分是否意味着不可能递归?
例如,要添加各种宏参数的列表:
#define RECURSE(mFIRST, ...) + mFIRST __VA_OPT__(RECURSE(__VA_ARGS__))
int main(int argc, char const* const argv[])
{
return 1 RECURSE(2, 3, 4);
// Expected result: "return 1 + 2 + 3 + 4;"
}
GCC和Clang都在后处理过程中生成RECURSE
。
// NOTE: Below is the output from g++ -E
int main(int argc, char const* const argv[])
{
return 1 + 2 RECURSE(3, 4);
}
注意:如果可能的话,可以很容易地编写更复杂的各种宏,比如级联,因为您可以从__VA_OPT__
创建一个自定义的__VA_OPT__
,它允许为1和2+参数提供完全独立的代码。
发布于 2021-06-07 21:22:29
答案是肯定的!在某种程度上,您已经可以使用在C中有递归宏,您可以在C++20中这样做,而__VA_OPT__
使一些事情变得更好。
下面是您可以做的事情的一个例子(附有解释):定义一个FOR_EACH
宏,它将宏应用于一堆参数,比__VA_OPT__
之前必须做的可怕的事情要好得多
#define PARENS () // Note space before (), so object-like macro
#define EXPAND(arg) EXPAND1(EXPAND1(EXPAND1(EXPAND1(arg))))
#define EXPAND1(arg) EXPAND2(EXPAND2(EXPAND2(EXPAND2(arg))))
#define EXPAND2(arg) EXPAND3(EXPAND3(EXPAND3(EXPAND3(arg))))
#define EXPAND3(arg) EXPAND4(EXPAND4(EXPAND4(EXPAND4(arg))))
#define EXPAND4(arg) arg
#define FOR_EACH(macro, ...) \
__VA_OPT__(EXPAND(FOR_EACH_HELPER(macro, __VA_ARGS__)))
#define FOR_EACH_HELPER(macro, a1, ...) \
macro(a1) \
__VA_OPT__(FOR_EACH_AGAIN PARENS (macro, __VA_ARGS__))
#define FOR_EACH_AGAIN() FOR_EACH_HELPER
FOR_EACH(F, a, b, c, 1, 2, 3) // => F(a) F(b) F(c) F(1) F(2) F(3)
https://stackoverflow.com/questions/51166178
复制相似问题