##:如果参数不存在则忽略逗号和参数
...:可变参数
栗子:
#define Debug(fmt, args...) LOG("DEBUG", fmt, ##args)
-
...:
...是C和C++预处理器中的一个特殊标记,用于表示一个可变数量的参数。- 在宏定义中,可以使用
...来表示宏可以接受任意数量的参数。 - 在宏体内部,可以使用
__VA_ARGS__(注意是两个下划线)来引用这些参数。但在上面的例子中,实际上使用了args...作为参数名,并在宏体内部直接使用了args。这是可以的,只要在宏体内部正确地引用了这些参数。
-
##args:
##是C和C++预处理器中的另一个特殊标记,称为“参数连接符”(token-pasting operator)。- 当宏的参数列表中包含可变参数,并且希望在某些情况下忽略这些参数时(例如,当这些参数没有被实际提供时),
##是非常有用的。 - 在上面的例子中,
##args的作用是:如果args为空(即没有提供额外的参数),则预处理器会忽略,和args,从而避免在编译时产生语法错误。
考虑以下情况:
Debug("Hello"); // 宏展开为:LOG("DEBUG", "Hello")
Debug("Hello, %d", 5); // 宏展开为:LOG("DEBUG", "Hello, %d", 5)
在第一个例子中,因为 args 没有被提供,所以预处理器使用 ##args 来忽略 , 和 args,从而避免在 LOG 函数调用中产生多余的逗号。