我正在尝试创建一些使用可变参数的跟踪宏。仅当命名参数位于可变参数之前,这些宏才能正常运行。
下面显示了我正在做的最小代码版本。只有不带参数的TraceTest()失败。我还尝试创建一个中间宏,该宏将一个虚拟的第一个参数传递给TraceTest1,但是也失败了。
template<typename ...Args>
inline void f(const char*, Args&&... args) { }
#define TraceTest1(a, args...) f("Trace Start ", ##args)
#define TraceTest(args...) f("Trace Start", ##args)
TraceTest(); // error: expected primary-expression before ‘)’ token
TraceTest("a"); // works
TraceTest1(); // works
TraceTest1("a"); // works
我已经阅读了有关可变参数宏的gnu文档,但找不到任何可以解释这一点的东西。
我正在Ubuntu 18.04下使用gcc 7.4.0并使用
进行编译g++ -Wall -Wextra -std=c++17 src/event.cpp -obin/event
答案 0 :(得分:1)
TraceTest()
扩展为f("Trace start",)
,这显然是语法错误。
命名的可变参数宏参数和令牌标记','和可变参数宏参数都不是标准的C ++(即使我能找到的每个编译器都实现了后者)。如果您希望将它们与GCC一起使用,请使用“ -std = gnu ++ 17”而不是“ -std = c ++ 17”。
请注意,C ++ 20正在添加一个新的__VA_OPT__
预处理器令牌,该令牌可用于移植:
#define TraceTest(...) f("Trace Start " __VA_OPT__(,) __VA_ARGS__)
__VA_OPT__
仅在__VA_ARGS__
不为空时被其参数替换,因此TraceTest()
将被f("Trace Start ")
替换。