可变宏中的参数计数无效 [英] Invalid argument count in a variadic macro
问题描述
我试图创建一个宏,它将迭代一个定义的术语列表,并为每个调用另一个宏,可能有额外的参数列表。这是我得到的:
#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 __ / code>,它们被传递到后续的宏,而不是之前。这也导致过去的问题,例如在这里 -
为什么这个可变参数计数宏与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 theMACRO
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屋!