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