我得到了以下实现来获取可变参数宏中的参数数量(目前限制为16个参数)。但是,对于VS2010,无论传递多少个参数,输出始终为1
。 With GCC,输出是正确的,让我得出结论,我一定错过了MSVC(10)特有的东西。
#define PP_NARGS(...) \
_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N
int main(){
int i = PP_NARGS(A,V,C,X,Y,Z);
std::cout << i;
std::cin.get();
return 0;
}
所以,问题就像标题所述,任何帮助都会受到赞赏。
答案 0 :(得分:23)
以下解决方法是否有帮助?
#define EXPAND(x) x
#define PP_NARGS(...) \
EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
我认为你的宏没有特别错,但是
MSVC的__VA_ARGS__
扩展似乎与C99的行为不同。
答案 1 :(得分:1)
问题似乎是Visual Studio在将传递到后续宏之后展开__VA_ARGS__
,而gcc在传递之前将其扩展。
在您的情况下,PP_NARGS(A,V,C,X,Y,Z)
将A,V,C,X,Y,Z
绑定到__VA_ARGS__
,然后将其作为一个整体传递给_xPP_NARGS_IMPL
。
作为测试,运行:
#define PP_NARGS(...) \
_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)
#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) \
(std::cout << #x1 << std::endl, N)
int main() {
int i = PP_NARGS(A, V, C, X, Y, Z);
std::cout << i;
return 0;
}
您会在屏幕上看到A, V, C, X, Y, Z
,而不仅仅是A
正如您所期望的那样。
正如Ise Wisteria所建议的那样,可能的解决方案是通过以下方式强制扩展:
#define EXPAND(x) x
#define PP_NARGS(...) \
EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0))
答案 2 :(得分:-9)
__VA_ARGS__
是C99语言功能
VC ++不是C99编译器
做数学。
这就像尝试使用Scheme编译器编译Pascal并发现奇怪它不适用于'开始/结束'对。
我不知道C ++和Visual Studio在这一切中的表现如何。