2010-08-25 111 views
7

考虑这个宏:可变参数的宏零个参数,和逗号

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ > 

当与零个参数使用它产生坏的代码,因为编译器期望逗号之后的标识符。事实上,VC的预处理器足够聪明,可以删除逗号,但GCC不是。 由于宏不能超载,好像它需要一个单独的宏这种特殊情况下得到它的权利,如:

#define MAKE_TEMPLATE_Z() template <typename T> 

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

回答

9

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

较早的预处理程序,显然包括GCC在回答最初编写时,有时候会根据您的希望解释一个空的参数列表,但共识已经转向更严格,更窄的扩展,这更符合标准。

得到的答案下面工作,省略号之前定义一个额外的宏参数:

#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模式,这是远优选的。

+0

谢谢。顺便说一句,这是标准的行为,还是一个GCC的东西? – uj2 2010-08-25 06:14:54

+1

@ uj2:这是GCC;标准只禁止空的可变参数列表。顺便说一句,这是混合C99与C++,所以这段代码是严格的非标准的,除非你在C++ 0x ...在这种情况下,你应该... – Potatoswatter 2010-08-25 06:16:48

+0

不介意模板,它只是一个玩具的例子。这怎么会是0x,C++ 98/03没有定义可变宏? – uj2 2010-08-25 06:22:13

1

在GCC的情况下,你需要把它写这样的:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ > 

如果__VA_ARGS__是空的,GCC的预处理器去除了之前的逗号。

0

首先要小心可变宏不是当前C++的一部分。看来他们会在下一个版本中。目前他们只有在C99编程时才符合要求。

对于零参数的可变参数宏,有一些技巧可以检测到这一点,并在宏周期中对其进行编程。 Googel为empty macro arguments