可变宏中的参数计数无效 [英] Invalid argument count in a variadic macro

查看:156
本文介绍了可变宏中的参数计数无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个宏,它将迭代一个定义的术语列表,并为每个调用另一个宏,可能有额外的参数列表。这是我得到的:

  #define ITERATE_OVER_TERMS(MACRO,...)\ 
MACRO ,__VA_ARGS__)\
MACRO(Term2,__VA_ARGS__)\
MACRO(Term3,__VA_ARGS__)\
...等等



但是,当我试图在Visual Studio 2015中使用它时,会出现错误

 警告C4003:宏'BODY'的实际参数不足

其中 BODY 是作为 MACRO 参数传递的宏的名称。



为了缩小错误范围,我将我的示例缩减为以下内容:

p>

  #include< iostream> 

#define ITERATE(MACRO,...)\
MACRO(1,__VA_ARGS__)MACRO(2,__VA_ARGS__)

#define BODY(IterationArg, Arg1,Arg2)\
std :: cout<< IterationArg<< Arg1<< Arg2< std :: endl;

int main(){
ITERATE(BODY,8,9)
return 0;
}

它给我的错误如上所示,而我期望它编译成功并产生输出

  189 
289

它似乎用g ++编译,但不是Visual Studio。
我缺少什么?

解决方案

问题是Visual Studio扩展 __ VA_ARGS __ ,它们被传递到后续的宏,而不是之前。这也导致过去的问题,例如在这里 -
为什么这个可变参数计数宏与VC ++失败?



在你的情况下, / p>

  #include< iostream> 

#define ITERATE(MACRO,...)\
MACRO(1,__VA_ARGS__)MACRO(2,__VA_ARGS__)

#define BODY(IterationArg, Arg1,Arg2)\
std :: cout<< #Arg1<< std :: endl;

int main(){
ITERATE(BODY,8,9)
return 0;
}

参数#Arg1 是字符串,显示我们在输出中的内容:

  8,9 
8,9

不是我们预期的,是吗?



与链接问题相同:通过虚拟 EXPAND 宏强制扩展:

  #define EXPAND(x)x 

#define ITERATE(MACRO,...)\
EXPAND(MACRO(1,__VA_ARGS__))EXPAND(MACRO __VA_ARGS__))

这将在VS和gcc中提供所需的结果。


I am trying to create a macro that would iterate over a defined list of terms, and for each invoke another macro, possibly with additional argument list. Here is what I have got:

#define ITERATE_OVER_TERMS(MACRO, ...) \
MACRO(Term1, __VA_ARGS__) \
MACRO(Term2, __VA_ARGS__) \
MACRO(Term3, __VA_ARGS__) \
... and so on

However, when I was trying to use it with Visual Studio 2015, i get an error

warning C4003: not enough actual parameters for macro 'BODY'

where BODY is the name of the macro passed as the MACRO argument. While technically a warning, it shows that something has gone wrong with the expansion.

In an attempt to narrow down the error, I reduced my example to the following:

#include <iostream>

#define ITERATE(MACRO, ...) \
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__)

#define BODY(IterationArg, Arg1, Arg2) \
std::cout << IterationArg << Arg1 << Arg2 << std::endl;

int main() {
  ITERATE(BODY, 8, 9)
    return 0;
}

It gives me the error as shown above, while I expected it to compile succesfully and produce the output

189
289

It does seem to compile with g++, but not Visual Studio. What am I missing? Is there some walkaround for this to work?

解决方案

The problem is that Visual Studio expands __VA_ARGS__ after they are being passed into a subsequent macro, and not before. This has caused problems in the past as well, for example here -- Why does this variadic argument count macro fail with VC++?

In your case, consider a simple change in the code:

#include <iostream>

#define ITERATE(MACRO, ...) \
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__)

#define BODY(IterationArg, Arg1, Arg2) \
std::cout << #Arg1 << std::endl;

int main() {
  ITERATE(BODY, 8, 9)
    return 0;
}

The argument #Arg1 is stringified, showing us its contents in the output:

8, 9
8, 9

Not what we expected, huh?

A solution is the same as in the linked question: force an expansion through a dummy EXPAND macro:

#define EXPAND(x) x

#define ITERATE(MACRO, ...) \
EXPAND(MACRO(1, __VA_ARGS__)) EXPAND(MACRO(2, __VA_ARGS__))

This gives you the desired result both in VS and gcc.

这篇关于可变宏中的参数计数无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆