11

考虑这个宏:

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

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

#define MAKE_TEMPLATE_Z() template <typename T>

有什么方法可以在不引入第二个宏的情况下使其工作?

4

3 回答 3

13

不,因为宏调用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 模式下的可变参数模板,这是更可取的。

于 2010-08-25T06:05:20.950 回答
3

如果是 GCC,你需要这样写:

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

如果__VA_ARGS__为空,GCC 的预处理器会删除前面的逗号。

于 2010-08-25T06:07:41.867 回答
1

首先要注意可变参数宏不是当前 C++ 的一部分。他们似乎将在下一个版本中。目前,它们只有在您使用 C99 编程时才符合要求。

对于具有零参数的可变参数宏,有一些技巧可以检测到这一点并围绕它进行宏编程。用于空宏参数的 Googel 。

于 2010-08-25T07:04:38.900 回答