考虑这个宏:
#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ >
当使用零参数时,它会产生错误代码,因为编译器需要逗号后面的标识符。实际上,VC的预处理器足够聪明,可以删除逗号,但GCC不是。 由于宏不能重载,似乎需要一个单独的宏才能使这个特殊情况正确,如:
#define MAKE_TEMPLATE_Z() template <typename T>
有没有办法让它在没有引入第二个宏的情况下工作?
答案 0 :(得分:10)
不,因为宏调用MAKE_TEMPLATE()
根本没有零参数;它有一个包含零令牌的参数。
较早的预处理器,显然包括最初编写此答案时的GCC,有时会按照您的意愿解释为空参数列表,但共识已经转向更严格,更窄的扩展,更符合标准。< / p>
要获得以下答案,请在省略号之前定义一个额外的宏参数:
#define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ >
然后在列表不为空时在第一个参数之前总是放一个逗号:
MAKE_TEMPLATE(, foo )
根据http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html,GCC确实支持这一点,而不是透明。
语法是:
#define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ >
无论如何,两者都支持C ++ 0x模式的可变参数模板,这是更好的选择。
答案 1 :(得分:1)
如果是GCC,你需要这样写:
#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ >
如果__VA_ARGS__
为空,GCC的预处理器将删除前面的逗号。
答案 2 :(得分:0)
首先要注意,可变参数宏不是当前C ++的一部分。看来它们将会出现在下一个版本中。目前,如果您使用C99进行编程,它们只符合要求。
对于零参数的可变参数宏,有一些技巧可以检测到这种情况并对其进行宏编程。 Googel为empty macro arguments。