我正在处理一个递归宏。但是,它似乎没有递归扩展。这是一个最小的工作示例,以显示我的意思:
// ignore input, do nothing
#define ignore(...)
// choose between 6 names, depending on arity
#define choose(_1,_2,_3,_4,_5,_6,NAME,...) NAME
// if more than one parameter is given to this macro, then execute f, otherwise ignore
#define ifMore(f,...) choose(__VA_ARGS__,f,f,f,f,f,ignore)(__VA_ARGS__)
// call recursively if there are more parameters
#define recursive(first,args...) first:ifMore(recursive,args)
recursive(a,b,c,d)
// should print: a:b:c:d
// prints: a:recursive(b,c,d)
recursive
宏应该递归扩展,并始终连接结果,用冒号分隔。但是,它不起作用。正确生成递归宏(可以在结果a:recursive(b,c,d)
上看到,其中包括对宏的良好形式的调用),但生成的递归调用不会被扩展。
为什么会这样,我怎样才能得到我想要的行为?
答案 0 :(得分:4)
您无法获得所需的行为。根据设计,C预处理器并不是完整的。
您可以使用多个宏来获取多个替换,但是无法通过任意数量的替换实现真正的递归。
答案 1 :(得分:1)
编译器预处理器不会重新展开您定义的宏。也就是说,它将盲目地用在定义中找到的字符串替换宏语句中找到的任何字符串。例如,Can we have recursive macros?或Macro recursive expansion to a sequence和C preprocessor, recursive macros
也就是说,recursive(a,b,c,d)
将扩展为a:recursive(b,c,d)
,然后预处理器将继续到基本代码中的下一行。它不会循环尝试继续扩展字符串(请参阅我引用的链接)。
答案 2 :(得分:1)
正如其他人所提到的,使用C宏不可能进行纯递归。但是,可以模拟类似递归的效果。
Boost预处理器工具可以很好地用于C和C ++,并且是一个独立的库:
http://www.boost.org/doc/libs/1_60_0/libs/preprocessor/doc/index.html