Here are two lines I saw in 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)
I guess it is to count the number of variadic arguments passing to CV_VA_NUM_ARGS
. Take following code for example:
CV_VA_NUM_ARGS(a,b,c)
will be extended to
CV_VA_NUM_ARGS_HELPER(a,b,c,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
At this point, I am stuck on understanding what is going on. Concretely, I don't know the utility of _1
, _2
,etc. Can anyone help me out? Here is a similar post while more complex to me.
EDIT: When I pass no arguments(say CV_VA_NUM_ARGS_HELPER()
), the macro will be replaced by 1 instead of 0, why is that?
_1
to _10
are just placeholders from the start in order to make sure N
is positioned over the correct number from 10
to 0
(depending on __VA_ARGS__
). They serve no purpose other than occupying a position.
Since each macro parameter must have a distinct identifier, those identifiers are as good as any.
Regarding your edit, that is limitation of the preprocessor. An empty token sequence is a valid argument to a macro. So it really is a single argument, because __VA_ARGS__ ,
(note the comma) becomes such an argument.
It's quite a known issue, so much so that C++20 added the __VA_OPT__
preprocessor macro. It allows to add the comma conditionally. On C++20, the implementation can be fixed to work as expected like this:
#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)
There is nothing special about _1
, _2
etc. You can have i
, j
, k
in their place.
The value of N depends on the number of arguments you have passed because N becomes the 11th element in the macro expansion (because of the 10 place holders).
So for CV_VA_NUM_ARGS(a,b,c)
, the 11th element is 3. For CV_VA_NUM_ARGS(a,b,c,d,e,f)
, the 11th element is 6 and so on.
Note that with this particular code you can count only up to 10 arguments. Using more than 10 arguments will generate a compiler error.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.