变量宏,零参数
我正在研究一个调用宏,
#define CALL(f,...) FN(f)->call((ref(new LinkedList()), __VA_ARGS__))
什么时候叫,
CALL(print,2,3,4,5);
将2 3 4 5添加到链接列表(,重载以执行此操作)并调用print,其中需要一个按预期工作的链表,但是有些调用不需要参数,
CALL(HeapSize);
它仍然需要一个链接列表,但是空的一个,上面不起作用,我试图想出一个可以使用任何一种风格的宏吗?
编辑:挖掘gcc文档我发现在VA_ARGS之前添加##会删除,当没有参数但是我无法嵌套宏时,
CALL(print,CALL(HeadSize));
这会导致CALL未定义错误,如果我分离它的工作调用
至于更新的问题,通过使用如下的辅助宏VA_ARGS
,参数将按预期扩展。
#define VA_ARGS(...) , ##__VA_ARGS__ #define CALL(f,...) FN(f)->call((ref(new LinkedList()) VA_ARGS(__VA_ARGS__)))
如果你正在使用gcc / g ++,有一种方法:
#define CALL(f,...) FN(f)->call((ref(new LinkedList()), ## __VA_ARGS__))
从精细手册 :
[…]如果省略了变量参数或为空,则`##’运算符会使预处理器删除之前的逗号。
所以gcc专门针对你所面临的问题进行扩展/破解。
如果您正在使用GCC,它有一个扩展名以吞下__VA_ARGS__
之前的逗号。 请参阅: http : //gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html 。
这些答案中的一个共同主题是我们需要GCC特定的黑客攻击。 一种方法是使用令牌粘贴##__VAR_ARGS__
,但粘贴的参数不是宏扩展的,这意味着宏不能嵌套。 但是如果你打算做一些GCC特定的事情,那么为什么不使用老式的GCC扩展:
#define VARARG_FOO(ZeroOrMoreArgs...) \ printf("VARARG_FOO: " ZeroOrMoreArgs)
ZeroOrMoreArgs
简单地被所有参数(如果有的话),逗号和所有参数替换。 这包括递归宏扩展。
- 然后
VARARG_FOO()
扩展为printf("VARARG_FOO: ")
- 和
VARARG_FOO("I iz %d", 42)
扩展为printf("VARARGFOO: " "I iz %d", 42)
最后
#define NEST_ME "I tawt I taw a puddy tat" VARARG_FOO("The evil one says %s", NEST_ME);
将扩大到
printf("VARARG_FOO: " "The evil one says %s", "I tawt I taw a puddy tat");
优点:
- 您可以嵌套宏调用,同时具有零或更多的aguments。
缺点:
-
##__VA_ARGS__
hack在标准C程序中可能无害,因为它们总是至少有一个逗号。 (我没想过这是不是真的)。 - 据@ScootMoonen称,
##__VA_ARGS__
hack是MSVC的无证扩展。
不幸的是,这是无法做到的。 您需要定义一个单独的宏来执行此调用。
当VA_ARGS被替换为无效时,你最终得到了无效的参数,你最终会浮动,
#define CALL0(f) FN(f)->call((ref(new LinkedList())))
简单地使f
成为...
一部分,并使用单独的宏来提取您需要f
的第一个参数。