问题标签 [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 回答
1485 浏览

c++ - 在 Vardiadic 宏中展开 Variadic 模板(如何从目标函数中提取参数名称)

我正在努力解决具有挑战性但又简单的问题。假设我有一个目标函数如下

我想“提取”的是变量名(即'arg1','arg2')。例如,通过一些预处理为变量获取此信息是微不足道的

如果有多个变量,我也可以使用可变参数宏

但我不知道如何从目标函数中“提取”..例如,使用可变参数模板技术如下

它行不通:我将获得 'A...' 而不是解压的变量,当然...任何提示?

谢谢!注意:我使用的是 C++11,gcc 4.8.1

0 投票
1 回答
77 浏览

c++ - Variadic Macros 需要一个无意义的宏来让它工作?

以下代码在 VC++ 2012 上是可以的

FOO不使用宏就无法编译。它显示的实际参数不够MAX_OF_2。为什么或编译器的任何错误?

0 投票
0 回答
249 浏览

c++ - MSVC 中宏的可变参数计数

我正在使用这个简单的宏来记录我的程序的事件:

它使用 GCC 和 MinGW 在 Linux 和 Windows 上愉快地编译。虽然 MSVC 11 无法编译。

注意:我在理解这一点之前的 SO 问题的答案时遇到了困难。我想我遗漏了一些关于宏和/或可变参数计数的东西。所以:

  1. 是什么__VA_ARGS__?我必须使用它吗?
  2. 我是否必须将它用于 MSVC 可编译代码?
  3. __VA_ARGS__由于缺乏这些人员,上面的代码是错误的/非标准的/不优雅的吗?
0 投票
1 回答
80 浏览

c++ - 如何使用宏来构造一个类?

例如,我有一堂课

我想用宏来替换构造函数,比如

并且元素的数量是可变的(需要...可变参数宏)。

有可能做到吗?谢谢

0 投票
2 回答
267 浏览

c++ - 可变宏参数

我有一个断言宏,它看起来像:

MyLogFunction也是一个可变参数模板:

除了我不想在断言调用中插入其他信息的情况外,一切都运行良好。

所以这很好用:

但这不是:

我相信有一种方法可以处理没有可变参数参数已传递给宏调用的情况,并且有一种方法可以插入简单字符串之类的东西""而不是__VA_ARGS__

0 投票
2 回答
3962 浏览

c++ - 使用可变参数宏或模板来实现一组函数

我有一组用于实例化和初始化一组对象的方法。它们看起来都差不多,除了传递给Init函数的参数数量:

请注意,除了传递给Init函数外,不得在任何地方使用这些参数。

我想找到一种方法来实现所有这些,而不必为每种对象类型复制代码。


我尝试使用可变参数宏,结果如下(无效):

现在,在这个实现中,我使用了 VA_ARGS 两次,两次都错误:

  • 在第一种情况下,我想要一个具有我指定类型的参数列表(Arg1 a1,Arg2 a2...)

  • 在第二种情况下,我想通过它们的名称( Init(a1, a2...) )调用这些参数。


我尝试使用可变参数模板:

...但这似乎也不起作用,我在模板定义行上收到以下错误:

错误 C2143:语法错误:在 '...' 之前缺少 ','

错误 C2065:“Args”:未声明的标识符

我正在使用VS2012。

我仍然可以为每个数量的参数编写 N 个类似的宏,但是我想知道是否有一种方法可以在不重复代码的情况下获得相同的结果?

0 投票
3 回答
12306 浏览

c - 使用 __VA_ARGS__ 定义字符串化宏时出错

我一直在尝试在 C 中实现一个函数宏,该函数宏在参数前面加上“DEBUG:”,并将其参数传递给 printf:

这在 gcc 中给了我这个错误:

据说,它应该对格式进行字符串化,并将其变量参数传递给 printf,但到目前为止我无法克服这个错误。


编辑

在放弃字符串化参数和双重哈希(##)之后,__VA_ARGS__我现在遇到了这个错误:

我应该在参数后加逗号吗?

作为参考,DBG() 现在看起来像这样:

0 投票
2 回答
505 浏览

c++ - 宏调用中的#ifdef 适用于 gcc 但不适用于 msvc

我有一个宏 TYPELIST,它接受可变参数。我想要类似的东西

这与 gcc 完美配合。但是,当我尝试使用 MSVC 编译它时,它会将 ifdef 和 endif 解析为宏参数。我知道一种方法是将宏调用放在 ifdef 中。但是,如果我有一个巨大的列表,并且如果我想根据定义的不同宏包含不同的类,那将变得乏味。为什么这在 gcc 中有效,而不是在 MSVC 中有效?

0 投票
1 回答
716 浏览

c++ - 向 C 风格的可变参数列表添加额外的参数

我正在尝试为像 printf 这样的 C 风格的可变参数函数编写一个包装器,它添加了一些额外的参数,但我遇到了麻烦:

但我写/* the variadic arguments */什么?

即使我要包装的函数有一个需要 a 的版本va_list,我也做不到:

extra_arg1extra_arg2并且args不要神奇地变成va_list期望的vprintf

我知道我可以编写一个宏并使用__VA_ARGS__

但我试图避免这种情况并将包装器编写为函数。有没有办法做到这一点?

(顺便说一句,我也不能使用 C++11 可变参数模板。)

0 投票
2 回答
19732 浏览

c++ - 使用模板元编程的更好的 LOG() 宏

典型的基于 LOG() 宏的日志记录解决方案可能如下所示:

这允许程序员使用方便且类型安全的流操作符创建数据丰富的消息:

问题是这会导致编译器内联多个 ostream::operator<< 调用。这会增加生成的代码并因此增加函数大小,我怀疑这可能会损害指令缓存性能并阻碍编译器优化代码的能力。

这是一个“简单”的替代方法,它用对可变参数模板函数的调用替换内联代码:

********* 解决方案#2:可变模板函数 *********

编译器会根据需要根据消息参数的数量、种类和顺序自动生成模板函数的新实例。

好处是每个呼叫站点的指令更少。缺点是用户必须将消息部分作为函数参数传递,而不是使用流操作符组合它们:

********* 解决方案#3:表达式模板 *********

在@DyP 的建议下,我创建了一个使用表达式模板的替代解决方案:

表达式模板解决方案允许程序员使用熟悉的方便且类型安全的流操作符:

但是,当Part<A, B>内联创建时,不会进行 operator<< 调用,这给我们带来了两全其美的好处:方便且类型安全的流式操作符 + 更少的指令。带有 -O3 的 ICC13 生成以下汇编代码:

总共有 19 条指令,包括一个函数调用。流式传输的每个附加参数似乎都增加了 3 条指令。编译器根据消息部分的数量、种类和顺序创建不同的 Log() 函数实例化,这解释了奇怪的函数名称。

********* 解决方案 #4:CATO 的表达式模板 *********

这是 Cato 的出色解决方案,通过调整来支持流操纵器(例如 endl):

正如 Cato 所指出的,与上一个解决方案相比,它的好处是它可以减少函数实例化,因为 const char* 专门化处理所有字符串文字。它还导致在调用站点生成的指令更少:

如果您能想到任何方法来提高此解决方案的性能或可用性,请告诉我。