首页 > 代码库 > C/C++ 使用宏在编译期计算可变参数个数

C/C++ 使用宏在编译期计算可变参数个数

参考https://groups.google.com/forum/#!forum/comp.std.c/d-6Mj5Lko_s

同时参考了cppformat源代码


C++是不提倡可变参数,理由不说了。但是类似printf的函数族使用起来确实很方便,我在查找printf的替代方案时无意间看到的。感慨下,微软的CString::Format确实很好用

cppformat提供类似printf的功能,但是又是类型安全的,其核心是利用C++强大的模版功能。在实现上,cppformat实现了在编译期计算可变参数个数,原理就是https://groups.google.com/forum/#!forum/comp.std.c/d-6Mj5Lko_s里面讨论的


为简便起见,这里只以最多三个可变参数做讨论

#define   ARG_N(a1,a2,a3,N,...)  N
这个宏的作用是,截取并返回参数列表的第四个参数

#define  ARG_N_HELPER(...)  ARG_N(__VA_ARGS__)
辅助宏,为使结果计算正确


#define  COUNT_ARG(...)  ARG_N_HELPER(__VA_ARGS__,3,2,1,0)
计算可变参数个数宏,可变参数个数在   大于0,小于等于3   内范围内计算正确


例如:

COUNT_ARG(x)     ->  1
COUNT_ARG(x,y)   ->  2
COUNT_ARG(x,y,z) ->  3

以COUNT_ARG(x,y)为例,示意计算过程
COUNT_ARG(x,y)
-> ARG_N_HELPER(X,Y,3,2,1,0)
-> ARG_N(X,Y,3,2,1,0)  截取第四个参数  2


另外,在VC编译器上,编译可能会失败需要定义下面的宏

#define  ARG_T(t)  t
#define  ARG_N_HELPER(...)  ARG_T(ARG_N(__VA_ARGS__))

完整的宏如下

#define ARG_T(t)  t  //解决VC编译错误
#define ARG_N(a1,a2,a3,N,...)  N  //截取并返回第四个参数,这里限制了可变参数计算的范围[1,3]
#define ARG_N_HELPER(...)  ARG_T(ARG_N(__VA_ARGS__))   //辅助宏
#define COUNT_ARG(...)  ARG_N_HELPER(__VA_ARGS__,3,2,1,0)  //返回可变参数个数


示意代码

int main()
{
    int  argn = COUNT_ARG(1,2,3); //argn值为3    return 0;
}






C/C++ 使用宏在编译期计算可变参数个数