具有零参数的可变参数宏
我正在开发一个调用宏,
#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 not Defined 错误,如果我将称其有效
I am working on a call macro,
#define CALL(f,...) FN(f)->call((ref(new LinkedList()), __VA_ARGS__))
which when called,
CALL(print,2,3,4,5);
adds 2 3 4 5 to the linked list (, is overloaded to do so) and calls print which expects a linked list which works as expected how ever there are some calls which do not require arguments,
CALL(HeapSize);
It still takes a linked list but an empty one, above does not work, I am trying to come up with a macro that woud work with either style?
EDIT: Digging throug gcc docs I found that adding ## before VA_ARGS removes the , when there are no arguments but with that I can not nest macros,
CALL(print,CALL(HeadSize));
this causes CALL not defined error how ever if I separate the the calls it works
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
至于更新的问题,通过使用辅助宏
VA_ARGS
像接下来,参数将按预期扩展。
As for the updated question, by the use of auxiliary macro
VA_ARGS
likethe following, the arguments will be expanded as expected.
如果您使用 gcc/g++,有一种方法:
来自 精细手册:
所以 gcc 有一个专门针对您面临的问题的扩展/黑客。
If you're using gcc/g++ there is a way:
From the fine manual:
So gcc has an extension/hack specifically for the problem you are facing.
__VA_OPT__
(c++2a) 应该更可靠,例如:来自http://www.open-std。 org/jtc1/sc22/wg21/docs/papers/2016/p0306r2.html
__VA_OPT__
(c++2a) should be more reliable, eg:from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0306r2.html
如果您使用的是 GCC,它有一个扩展名可以吞掉
__VA_ARGS__
前面的逗号。请参阅:http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros .html。If you are using GCC, it has an extension to swallow up the comma preceding the
__VA_ARGS__
. See: http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html.只需将
f
作为...
的一部分,然后使用单独的宏在需要f
的位置提取第一个参数即可。Simply make
f
part of the...
, and use a separate macro to extract the first argument where you needf
.这些答案的一个共同主题是我们需要针对 GCC 的 hack。一种方法是使用标记粘贴
##__VAR_ARGS__
,但粘贴的参数不是宏扩展,这意味着宏不能嵌套。但是,如果您无论如何都要做一些 GCC 特定的事情,那么为什么不使用老式的 GCC 扩展:ZeroOrMoreArgs
简单地替换为所有参数(如果有)、逗号等。这包括递归宏扩展。VARARG_FOO()
扩展为printf("VARARG_FOO: ")
VARARG_FOO("I iz %d", 42)
扩展为printf("VARARGFOO: " "I iz %d", 42)
最后
将扩展为
优点:
缺点:
##__VA_ARGS__
hack 在标准 C 程序中可能是无害的,因为它们总是至少有一个逗号。 (我还没想过这是否属实)。##__VA_ARGS__
hack 是 MSVC 的未记录扩展。A common theme in these answers is that we need a GCC specific hack. One way is to use the token-paste
##__VAR_ARGS__
, but pasted arguments are not macro expanded, which means that macros cannot be nested. But if you are going to do something GCC specific anyway, then why not use the old-fashioned GCC extension:ZeroOrMoreArgs
is simply replaced by all the arguments (if any), commas and all. This includes recursive macro expansion.VARARG_FOO()
expands toprintf("VARARG_FOO: ")
VARARG_FOO("I iz %d", 42)
expands toprintf("VARARGFOO: " "I iz %d", 42)
Finally
will expand to
Pros:
Cons:
##__VA_ARGS__
hack might be harmless in standard C programs in the case where they always have at least one comma. (I haven't thought about whether this is true or not).##__VA_ARGS__
hack is an undocumented extension to MSVC.不幸的是,这无法做到。您需要定义一个单独的宏来执行此调用。
当 VA_ARGS 没有被替换时,你最终会得到无效的参数,你最终会得到一个浮动的
,
Unfortunately this cannot be done. You will need to define a separate macro to do this call.
As you end up with invalid arguments when VA_ARGS is substituted with nothing you end up with a floating
,