问题标签 [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.
c++ - __VA_ARGS__ 的问题
那里接受的答案对我不起作用。我已经尝试过使用 MSVC++ 10 和 g++ 3.4.5。
我还将示例压缩成更小的示例,并开始尝试在错误中向我打印一些信息:
在我看来, ARG_N 的论点最终是 'XXX' 而不是5,RSEQ_N
and much less 5,10,...,0
。g++ 的错误输出更具体地说是只提供了一个参数。
很难相信答案会被提出,然后在它完全不起作用时被接受,那么我做错了什么?为什么XXX
被解释为论点而不是被扩展?在我自己的混乱中,一切正常,直到我尝试将VA_ARGS传递给包含一些名称后跟 ... 的宏,如下所示:
我已经()
在各种不需要输入的宏中尝试了使用和不使用。
c++ - 如何挑出发送到仅采用可变参数的宏的第一个参数
我尝试获取发送到可变参数宏的第一个实际参数。这是我尝试过的,在 VS2010 中不起作用:
当我查看预处理器输出时,我看到它FIRST_ARG
返回发送到的整个参数列表MY_MACRO
......
另一方面,当我尝试:
它按预期扩展为 1。
这似乎与臭名昭著的两级 concat 宏解决的问题相反。我知道“宏参数在插入宏体之前已完全展开”但这似乎对我没有帮助,因为我不明白这在...的上下文中意味着什么__VA_ARGS__
显然__VA_ARGS__
绑定到N
并且仅在以后评估。我尝试了几种使用额外宏观级别的方法,但没有帮助。
c++ - 可变参数宏是非标准的吗?
对于调试构建,我通常使用 Clang,因为它可以更好地格式化警告和错误,并且更容易跟踪和修复它们。
但是最近在添加了一个带有可变参数的宏之后,Clang 告诉我以下内容(来自一个虚拟项目):
我知道macroname(args...)
在各种编译器中都能很好地编译,包括 Visualstudio、Sunstudio,当然还有 GCC。但为了确保 clang 是正确的,我尝试了另外两种扩展可变参数的方法:
1号:
2号:
在这两个我收到此消息:
...这让我想知道可变参数宏是否实际上是 C++ 标准的一部分(当然我知道预处理器是独立解释的)?
visual-c++ - MSVC 未正确扩展 __VA_ARGS__
考虑这段代码:
预期的输出X = 1 and VA_ARGS = 2, 3
适用于这两个宏,这就是我使用 GCC 得到的结果,但是,MSVC 将其扩展为:
也就是说,__VA_ARGS__
将其扩展为单个参数,而不是分解为多个参数。
有什么办法吗?
c++ - 使用宏迭代生成函数声明
我正在尝试使用宏生成函数声明
它将迭代地处理下一个(name)
或(type)
通过NAME
或PARAMS
分别,...
具有一个空的宏参数。但海湾合作委员会抱怨
铿锵的抱怨
我认为这是因为以下原因
因为我没有为这些...
or 中的每一个(name)
或(type)
. 我可以申请任何简单的工作吗?
我现在使用了一种类似于@James 使用的技术来查找参数列表的长度。如果作为第二个参数,而不是O
传递ONT
,我将打印逗号和NAME
。以下是最终解决方案:
测试:
c - 可变宏技巧
创建可变参数宏FOO(a1, a2, a3,..., an)
以使其扩展到您选择的任何预选有界范围内FOOn(a1, a2, a3,..., an)
的值的技巧是什么?n
也就是说,FOO(a)
应该扩展到FOO1(a)
、FOO(a, b, c)
toFOO3(a, b, c)
等。我知道有一个标准技巧,但我似乎找不到它。
请随时将此问题标记为重复问题,如果有其他问题的答案,请关闭它。我怀疑有,但我找不到。
c - GCC ##__VA_ARGS__ 技巧的标准替代方案?
例子:
根据 C99 标准,上面的使用BAR()
确实是不正确的,因为它会扩展为:
注意尾随逗号 - 不可行。
一些编译器(例如:Visual Studio 2010)会悄悄地为您摆脱尾随逗号。其他编译器(例如:GCC)支持将##
放在前面__VA_ARGS__
,如下所示:
但是有没有一种符合标准的方法来获得这种行为?也许使用多个宏?
现在,该##
版本似乎得到了很好的支持(至少在我的平台上),但我真的更愿意使用符合标准的解决方案。
先发制人:我知道我可以只写一个小函数。我正在尝试使用宏来做到这一点。
编辑:这是我为什么要使用 BAR() 的示例(虽然很简单):
这会自动在我的 BAR() 日志记录语句中添加一个换行符,假设fmt
始终是一个双引号 C 字符串。它不会将换行符打印为单独的 printf(),如果日志记录是行缓冲的并且来自多个异步源,这将是有利的。
c++ - 零参数的可变参数宏
我正在处理呼叫宏,
当被调用时,
将 2 3 4 5 添加到链表(,为此重载)并调用 print 期望链表按预期工作但是有一些不需要参数的调用,
它仍然需要一个链接列表,但是一个空列表,上面不起作用,我正在尝试提出一个适用于任何一种风格的宏?
编辑:通过 gcc 文档挖掘我发现在VA_ARGS之前添加 ##会删除 ,当没有参数但我不能嵌套宏时,
这会导致 CALL 未定义错误,但是如果我将其工作的调用分开
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 库以某种方式连接宏。但我不明白这如何适用于任意数量的参数,而且源代码是一个非常密集的预处理器代码集合,很难理解。
c++ - 具有“占位符”值的宏
我正在使用一个包含一组预处理器库的库。其中之一是 FOR_EACH 风格的宏,它遍历 a__VA_ARGS__
并为每个参数调用用户提供的宏。用户提供的宏调用如下:SOME_MACRO(current_arg)
但是,问题在于它仅适用于用户提供的带有单个参数的宏。我正在尝试做一些特别的事情,其中涉及 a 的名称struct
和结构中的每个字段。问题是,这需要宏的两个参数。
由于我正在使用的库只接受一元宏,有没有办法将附加参数“绑定”到我的宏?
到目前为止,我必须在宏中硬编码结构的名称。所以,如果struct
我正在使用的是 named Foo
,我不得不说:
有没有办法我可以将第二个参数“绑定”STRUCT
到宏,也许还有一些间接的,这样当库调用我的宏时,它就可以扩展为: