计算宏函数中可变参数的数量

时间:2018-12-19 08:27:36

标签: c++ c macros

这是我在OpenCV中看到的两行

#define CV_VA_NUM_ARGS_HELPER(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...)    N
#define CV_VA_NUM_ARGS(...)      CV_VA_NUM_ARGS_HELPER(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

我想这是要计算传递给CV_VA_NUM_ARGS的可变参数的数量。以下面的代码为例:

CV_VA_NUM_ARGS(a,b,c)

将扩展为

CV_VA_NUM_ARGS_HELPER(a,b,c,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

在这一点上,我坚持了解正在发生的事情。具体来说,我不知道_1_2等的实用工具。有人可以帮助我吗?这是一个类似的post,但对我来说却比较复杂。

编辑: 当我不传递任何参数(例如CV_VA_NUM_ARGS_HELPER())时,宏将被替换为1而不是0,为什么?

2 个答案:

答案 0 :(得分:2)

_1_10仅是占位符,以确保将N置于从100的正确数字上(取决于在__VA_ARGS__上)。他们除了担任职位外没有其他目的。

由于每个宏参数必须具有不同的标识符,因此这些标识符与任何标识符一样好。


关于您的编辑,这是预处理程序的限制。空令牌序列是宏的有效参数。因此它实际上是一个参数,因为__VA_ARGS__ ,(注意逗号)变成了这样一个参数。

这是一个众所周知的问题,以至于C ++ 20添加了__VA_OPT__预处理程序宏。它允许有条件地添加逗号。在C ++ 20上,实现可以像预期的那样固定进行工作:

#define CV_VA_NUM_ARGS(...)      CV_VA_NUM_ARGS_HELPER(__VA_ARGS__ __VA_OPT__(,) 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

答案 1 :(得分:1)

_1_2等没什么特别的。您可以将ijk放在他们的位置。

N的值取决于您传递的参数数量,因为N成为宏扩展中的第11个元素(因为有10个占位符)。

所以对于CV_VA_NUM_ARGS(a,b,c),第11个元素是3。 对于CV_VA_NUM_ARGS(a,b,c,d,e,f),第11个元素是6,依此类推。

请注意,使用此特定代码,您最多只能计算10个参数。使用10个以上的参数将产生编译器错误。