这是我在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,为什么?
答案 0 :(得分:2)
_1
至_10
仅是占位符,以确保将N
置于从10
至0
的正确数字上(取决于在__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
等没什么特别的。您可以将i
,j
,k
放在他们的位置。
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个以上的参数将产生编译器错误。