变量宏,零参数

我正在研究一个调用宏,

#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的第一个参数。