C++ 可变宏参数计数未按预期工作

C++ 可变宏参数计数未按预期工作,c++,visual-c++,macros,variadic-macros,C++,Visual C++,Macros,Variadic Macros,因此,基本上我尝试实现一个宏来计算VA_ARGS中的参数数量 为了简单起见,它最多只能工作3个参数。问题是,当使用的宏参数少于3个时,它不起作用,并触发“expected a expression”错误 只保留行,它会正确编译并打印“TEST PP\u NARG:3” 我相信问题可能是PP_RSEQ_N()由于某种原因只是扩展到了“3”,而不是“3,2,1,0”,因为即使PP_RSEQ_N()被定义为 #define PP_RSEQ_N() 10,9,8,7,6,5,4,3,2,1,0 如果参

因此,基本上我尝试实现一个宏来计算VA_ARGS中的参数数量

为了简单起见,它最多只能工作3个参数。问题是,当使用的宏参数少于3个时,它不起作用,并触发“expected a expression”错误

只保留行,它会正确编译并打印“TEST PP\u NARG:3”

我相信问题可能是PP_RSEQ_N()由于某种原因只是扩展到了“3”,而不是“3,2,1,0”,因为即使PP_RSEQ_N()被定义为

#define PP_RSEQ_N() 10,9,8,7,6,5,4,3,2,1,0
如果参数少于3个,它仍然无法工作


我正在使用MSVC编译器,这可能是问题的原因,因为它在宏中表现得不太好,如图所示:

在您的实现中
PP\u RSEQ\u N()
PP\u ARG\u N
的参数。作为一个参数,它仅在预处理的参数替换阶段展开,但这仅发生在替换其替换列表中的参数之前(只要在替换列表中,它未被字符串化且未参与粘贴)

由于
PP_ARG_N
在其替换列表中只有第四个参数
N
PP_RSEQ_N()
只有在传入三个参数时才会展开。(在重新扫描和替换阶段有第二次扫描,该扫描在参数替换后应用……但在这里没有效果,因为调用中提到了
PP_RSEQ_N()

去掉这个宏,把它放到
PP\u NARG
中,如下所示:

#define EXPAND( x ) x
#define PP_NARG(...) EXPAND(PP_ARG_N(__VA_ARGS__, 3,2,1,0))
#define PP_ARG_N(_1, _2, _3, N,...) N
…事情“运转”良好:

PP_NARG()
扩展为
1

PP\u NARG(x)
扩展为
1

PP_NARG(x,y)
扩展到
2


但是,请注意,
PP\u NARG()
不会给您0。可以说这实际上是正确的;对于预处理器,这不是传递零参数。它传递的是一个空的参数。这与定义X(A)打开关闭/
X()
产生
打开关闭
是一样的。如果出于某种原因,您希望将其扩展到0,那么可能会有一些骗局来实现这一点,但对于这个答案,我只关注如何让您克服这一困难。

经典的宏滥用示例。
#定义PP_ARG_N2(…)PP_ARG_N(u VA_ARGS_u)
?这是另一种尝试,这不仅仅是微软的做法——这是C规范规定的:当识别带有参数的宏时,将根据直接输入令牌流收集宏参数,而不进行宏扩展(目前)。参数中的宏将在收集参数后展开,然后再替换到主体中。
#define EXPAND( x ) x
#define PP_NARG(...) EXPAND(PP_ARG_N(__VA_ARGS__, 3,2,1,0))
#define PP_ARG_N(_1, _2, _3, N,...) N