Location>code7788 >text

The variable parameter list in C++ macro definition __VA_ARGS__ and the macros provided by QT_OVERLOADED_MACRO

Popularity:140 ℃/2025-04-09 11:59:00

1. Basic usage

VA_ARGSIt is a predefined macro in C/C++, used to represent a list of variable parameters (Variadic Arguments) in the macro definition, and needs to be used in conjunction with the ellipsis.... Its core function is to pass the mutable parameters in the macro call as is to the expanded code.

#define LOG(format, ...) printf(format, __VA_ARGS__)
 LOG("Value: %d", 42); // Expand as printf("Value: %d", 42)

Notice:VA_ARGSIt is impossible to directly access a single parameter in the mutable parameter list, nor to directly know how many parameters were passed.

2. Use of ##

whenVA_ARGSWhen empty, the above usage will have an error because there is an extra comma after the format. To avoid syntax errors, you need to use ## to tell the compiler to automatically remove the previous commas when the mutable parameter is empty.

#define LOG(format, ...) printf(format, ##__VA_ARGS__)
 LOG("Value: %d", 42); // Expand as printf("Value: %d", 42)
 LOG("some message"); // Expand as printf("some message")

3. Get the number of variable parameters

The common method is as follows, parameterNum() results in the number of input parameters.

#define get5th(a1, a2, a3, a4, a5, ...) a5
// ... getnth(a1, a2, a3, ... , an, ...) an
#define parameterNum(...) get5th(__VA_ARGS__, 4, 3, 2, 1)

parameterNum(a)
//get5th(a, 4, 3, 2, 1)
//1

parameterNum(a, b, c)
//get5th(a, b, c, 4, 3, 2, 1)
//3

However, when the number of __VA_ARGS__ parameters is 0, an extra comma will appear, and the calculation result is still 1, which requires further processing.

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N
#define COUNT_ARGS(...) __COUNT_ARGS(, ##__VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

COUNT_ARGS(a)
//__COUNT_ARGS(a, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
//1

COUNT_ARGS()
//__COUNT_ARGS(, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
//0

4. QT preset macros

QT provides macros for variable parameters in the file. When the number of single variable parameters is less than 10, you can directly use the macros provided by QT_OVERLOADED_MACRO(MACRO, ...).

#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
#define QT_VA_ARGS_EXPAND(...) __VA_ARGS__ // Needed for MSVC
#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##_##ARGC
#define QT_OVERLOADED_MACRO_IMP(MACRO, ARGC) QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
#define QT_OVERLOADED_MACRO(MACRO, ...) QT_VA_ARGS_EXPAND(QT_OVERLOADED_MACRO_IMP(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__))

Usage example:

#define sum_1(num1) num1
#define sum_2(num1, num2) num1 + num2
#define sum_3(num1, num2, num3) num1 + num2 + num3
#define sum_4(num1, num2, num3, num4) num1 + num2 + num3 + num4
#define sum_5(num1, num2, num3, num4, num5) num1 + num2 + num3 + num4 + num5

#define sum(...) QT_OVERLOADED_MACRO(sum,  __VA_ARGS__) 

int x = sum(1,2);
//int x = 1+2;
QString s = sum("a", "b");
// QString s = "a" +"b";

refer to:
C language variable parameter macro definition method
【Just For Fun】C - Macro Development - Select the nth parameter and expand different macros and defects according to the number of parameters
【Macro definition】——Get the number of parameters of variable parameter macros