问题标签 [variadic-macros]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
2156 浏览

c++ - __VA_ARGS__ 的问题

C++ 预处理器 __VA_ARGS__ 参数数量

那里接受的答案对我不起作用。我已经尝试过使用 MSVC++ 10 和 g++ 3.4.5。

我还将示例压缩成更小的示例,并开始尝试在错误中向我打印一些信息:

在我看来, ARG_N 的论点最终是 'XXX' 而不是5,RSEQ_Nand much less 5,10,...,0。g++ 的错误输出更具体地说是只提供了一个参数。

很难相信答案会被提出,然后在它完全不起作用时被接受,那么我做错了什么?为什么XXX被解释为论点而不是被扩展?在我自己的混乱中,一切正常,直到我尝试将VA_ARGS传递给包含一些名称后跟 ... 的宏,如下所示:

我已经()在各种不需要输入的宏中尝试了使用和不使用。

0 投票
1 回答
6839 浏览

c++ - 如何挑出发送到仅采用可变参数的宏的第一个参数

我尝试获取发送到可变参数宏的第一个实际参数。这是我尝试过的,在 VS2010 中不起作用:

当我查看预处理器输出时,我看到它FIRST_ARG返回发送到的整个参数列表MY_MACRO......

另一方面,当我尝试:

它按预期扩展为 1。

这似乎与臭名昭著的两级 concat 宏解决的问题相反。我知道“宏参数在插入宏体之前已完全展开”但这似乎对我没有帮助,因为我不明白这在...的上下文中意味着什么__VA_ARGS__

显然__VA_ARGS__绑定到N并且仅在以后评估。我尝试了几种使用额外宏观级别的方法,但没有帮助。

0 投票
4 回答
23558 浏览

c++ - 可变参数宏是非标准的吗?

对于调试构建,我通常使用 Clang,因为它可以更好地格式化警告和错误,并且更容易跟踪和修复它们。

但是最近在添加了一个带有可变参数的宏之后,Clang 告诉我以下内容(来自一个虚拟项目):

我知道macroname(args...)在各种编译器中都能很好地编译,包括 Visualstudio、Sunstudio,当然还有 GCC。但为了确保 clang 是正确的,我尝试了另外两种扩展可变参数的方法:

1号:

2号:

在这两个我收到此消息:

...这让我想知道可变参数宏是否实际上是 C++ 标准的一部分(当然我知道预处理器是独立解释的)?

0 投票
3 回答
20523 浏览

visual-c++ - MSVC 未正确扩展 __VA_ARGS__

考虑这段代码:

预期的输出X = 1 and VA_ARGS = 2, 3适用于这两个宏,这就是我使用 GCC 得到的结果,但是,MSVC 将其扩展为:

也就是说,__VA_ARGS__将其扩展为单个参数,而不是分解为多个参数。

有什么办法吗?

0 投票
2 回答
5878 浏览

c++ - 使用宏迭代生成函数声明

我正在尝试使用宏生成函数声明

它将迭代地处理下一个(name)(type)通过NAMEPARAMS分别,...具有一个空的宏参数。但海湾合作委员会抱怨

铿锵的抱怨

我认为这是因为以下原因

因为我没有为这些...or 中的每一个(name)(type). 我可以申请任何简单的工作吗?


我现在使用了一种类似于@James 使用的技术来查找参数列表的长度。如果作为第二个参数,而不是O传递ONT,我将打印逗号和NAME。以下是最终解决方案:

测试:

0 投票
3 回答
15690 浏览

c - 可变宏技巧

创建可变参数宏FOO(a1, a2, a3,..., an)以使其扩展到您选择的任何预选有界范围内FOOn(a1, a2, a3,..., an)的值的技巧是什么?n也就是说,FOO(a)应该扩展到FOO1(a)FOO(a, b, c)toFOO3(a, b, c)等。我知道有一个标准技巧,但我似乎找不到它。

请随时将此问题标记为重复问题,如果有其他问题的答案,请关闭它。我怀疑有,但我找不到。

0 投票
12 回答
86224 浏览

c - GCC ##__VA_ARGS__ 技巧的标准替代方案?

C99 中可变参数宏的空参数存在一个众所周知的 问题。

例子:

根据 C99 标准,上面的使用BAR()确实是不正确的,因为它会扩展为:

注意尾随逗号 - 不可行。

一些编译器(例如:Visual Studio 2010)会悄悄地为您摆脱尾随逗号。其他编译器(例如:GCC)支持将##放在前面__VA_ARGS__,如下所示:

但是有没有一种符合标准的方法来获得这种行为?也许使用多个宏?

现在,该##版本似乎得到了很好的支持(至少在我的平台上),但我真的更愿意使用符合标准的解决方案。

先发制人:我知道我可以只写一个小函数。我正在尝试使用宏来做到这一点。

编辑:这是我为什么要使用 BAR() 的示例(虽然很简单):

这会自动在我的 BAR() 日志记录语句中添加一个换行符,假设fmt始终是一个双引号 C 字符串。它不会将换行符打印为单独的 printf(),如果日志记录是行缓冲的并且来自多个异步源,这将是有利的。

0 投票
7 回答
28121 浏览

c++ - 零参数的可变参数宏

我正在处理呼叫宏,

当被调用时,

将 2 3 4 5 添加到链表(,为此重载)并调用 print 期望链表按预期工作但是有一些不需要参数的调用,

它仍然需要一个链接列表,但是一个空列表,上面不起作用,我正在尝试提出一个适用于任何一种风格的宏?

编辑:通过 gcc 文档挖掘我发现在VA_ARGS之前添加 ##会删除 ,当没有参数但我不能嵌套宏时,

这会导致 CALL 未定义错误,但是如果我将其工作的调用分开

0 投票
1 回答
540 浏览

c++ - Boost.Fusion 中的 C++ 可变参数宏?

因此,根据这个答案,C++ 不支持可变参数宏,并且 C++ 标准在任何地方都没有提到可变参数宏。我知道 C99 引入了带有__VA_ARGS__.

BOOST_FUSION_ADAPT_STRUCT现在,Boost.Fusion 中有一个功能,您可以使用宏将 Fusion 序列绑定到任意类或结构。这使您可以像使用 Fusion 序列一样使用您的类或结构。

这是一个如何使用它的示例(取自 Boost 文档):

现在,如果没有可变参数宏,这段代码怎么可能?该BOOST_FUSION_ADAPT_STRUCT宏似乎可以接受任意数量的参数,因为它可能可以与任意用户定义的类或结构一起使用。

我知道 Boost 以以有趣的方式弯曲 C++ 而闻名,但如果没有编译器的支持,这似乎是完全不可能的。那么 Boost.Fusion 用了什么样的魔法来实现这一目标呢?

PS:是的,我知道 Boost 是开源的。我做的第一件事是查看源代码。它似乎正在使用 Boost Preprocessor 库以某种方式连接宏。但我不明白这如何适用于任意数量的参数,而且源代码是一个非常密集的预处理器代码集合,很难理解。

0 投票
1 回答
1379 浏览

c++ - 具有“占位符”值的宏

我正在使用一个包含一组预处理器库的库。其中之一是 FOR_EACH 风格的宏,它遍历 a__VA_ARGS__并为每个参数调用用户提供的宏。用户提供的宏调用如下:SOME_MACRO(current_arg)

但是,问题在于它仅适用于用户提供的带有单个参数的宏。我正在尝试做一些特别的事情,其中​​涉及 a 的名称struct和结构中的每个字段。问题是,这需要宏的两个参数。

由于我正在使用的库只接受一元宏,有没有办法将附加参数“绑定”到我的宏?

到目前为止,我必须在宏中硬编码结构的名称。所以,如果struct我正在使用的是 named Foo,我不得不说:

有没有办法我可以将第二个参数“绑定”STRUCT到宏,也许还有一些间接的,这样当库调用我的宏时,它就可以扩展为: