Variadic宏,零参数和逗号

uj2*_*uj2 9 c c++ c-preprocessor variadic-macros

考虑这个宏:

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ >
Run Code Online (Sandbox Code Playgroud)

当使用零参数时,它会产生错误代码,因为编译器需要逗号后面的标识符.实际上,VC的预处理器足够聪明,可以删除逗号,但GCC不是.由于宏不能重载,看起来这个特殊情况需要一个单独的宏才能正确,如:

#define MAKE_TEMPLATE_Z() template <typename T>
Run Code Online (Sandbox Code Playgroud)

有没有办法让它工作而不引入第二个宏?

Pot*_*ter 12

不,因为宏调用MAKE_TEMPLATE()根本没有零参数; 它有一个包含零令牌的参数.

较早的预处理器,显然是在最初编写这个答案的时候包括GCC,有时会像你希望的那样解释为一个空的参数列表,但是共识已经转向更严格,更窄的扩展,这更符合标准.

要获得下面的答案,请在省略号之前定义一个额外的宏参数:

   #define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ >
Run Code Online (Sandbox Code Playgroud)

当列表不为空时,总是在第一个参数之前放一个逗号:

   MAKE_TEMPLATE(, foo )
Run Code Online (Sandbox Code Playgroud)

老答案

根据http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html,GCC支持这一点,只是不透明.

语法是:

   #define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ >
Run Code Online (Sandbox Code Playgroud)

无论如何,两者都支持C++ 0x模式的可变参数模板,这是更好的选择.