Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有零参数和逗号的可变宏_C++_C_C Preprocessor_Variadic Macros - Fatal编程技术网

C++ 具有零参数和逗号的可变宏

C++ 具有零参数和逗号的可变宏,c++,c,c-preprocessor,variadic-macros,C++,C,C Preprocessor,Variadic Macros,考虑这个宏: #define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ > #定义MAKE_模板(…)模板 当与零参数一起使用时,它会生成错误的代码,因为编译器希望在逗号之后有一个标识符。实际上,VC的预处理器足够聪明,可以删除逗号,但GCC的不够聪明。 由于宏不能重载,因此在这种特殊情况下,似乎需要一个单独的宏才能使其正确,如下所示: #define MAKE_TEMPLATE_Z() template <t

考虑这个宏:

#define MAKE_TEMPLATE(...) template <typename T, __VA_ARGS__ >
#定义MAKE_模板(…)模板
当与零参数一起使用时,它会生成错误的代码,因为编译器希望在逗号之后有一个标识符。实际上,VC的预处理器足够聪明,可以删除逗号,但GCC的不够聪明。 由于宏不能重载,因此在这种特殊情况下,似乎需要一个单独的宏才能使其正确,如下所示:

#define MAKE_TEMPLATE_Z() template <typename T>
#定义MAKE_TEMPLATE_Z()模板

有没有办法在不引入第二个宏的情况下使其工作?

没有,因为宏调用
make\u TEMPLATE()
根本没有零参数;它有一个包含零标记的参数

旧的预处理器,显然包括最初编写此答案时的GCC,有时会如您所希望的那样解释一个空参数列表,但共识已朝着更严格、更狭窄的扩展方向发展,更符合标准

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

   #define MAKE_TEMPLATE(UNUSED, ...) template <typename T, ## __VA_ARGS__ >
旧答案 据报道,GCC确实支持这一点,只是不透明

语法是:

   #define MAKE_TEMPLATE(...) template <typename T, ## __VA_ARGS__ >
#定义MAKE_模板(…)模板

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

对于GCC,您需要这样编写:

#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ >
#定义MAKE_模板(…)模板

<> >如果代码> VAGARGSXY<<代码>为空,GCC的预处理器删除前面的逗号。

< P>首先注意,变量宏不是当前C++的一部分。看来它们将出现在下一个版本中。目前,只有在C99中编程时,它们才符合要求


对于具有零参数的可变宏,有一些技巧可以检测到这一点并在其周围编写宏程序。Googel for.

谢谢。顺便说一句,这是标准行为还是gcc的东西?@uj2:这是gcc;该标准只是禁止空变量列表。顺便说一下,这是C99和C++的混合,所以这个代码严格不标准,除非你在C++ 0x……在这种情况下你应该…不要介意模板,这只是个玩具例子。这怎么一定是0x,C++98/03不是定义了可变宏吗?§16.3/9:“一个形式为
#define identifier lparen identifier listop)replacement list的预处理指令新行
定义了一个类似于宏的函数,在语法上类似于函数调用。”-仅此而已。@uj2:No,C++03没有可变宏或模板。C++0x提供了这两种功能。我认为您可以做到。我在这里做了非常类似的事情:。
#define MAKE_TEMPLATE(...) template <typename T, ##__VA_ARGS__ >