【发布时间】:2014-09-13 17:02:10
【问题描述】:
长话短说,gcc 和 vc++ 预处理器具有不同的输出和相同的输入。如果传递给另一个宏,似乎 vc++ 中的可变参数宏不会进行“参数匹配”(如果它是正确的术语)。 例如:
#define MACRO(a, ...) head:a, tail:MACRO_OTHER(__VA_ARGS__)
#define MACRO_OTHER(a, ...) head:a, tail:__VA_ARGS__
有
MACRO(1, 2, 3, 4, 5)
gcc 输出:
head:1, tail:head:2, tail:3,4,5
vc++ 输出:
head:1, tail:head:2,3,4,5, tail:
显然MACRO_OTHER 中的a 是2,3,4,5,带有空的可变参数部分。
考虑到这一点,有没有办法创建一个 vc++ 替代以下宏(与 gcc 配合得很好)
#define VA_TYPES_WITH_ARGS(...) __VA_TYPES_WITH_ARGS(VA_NUM_ARGS(__VA_ARGS__),##__VA_ARGS__)
#define __VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS(n,##__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS(n, ...) _VA_TYPES_WITH_ARGS_##n(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_0()
#define _VA_TYPES_WITH_ARGS_1(type ) type _arg1
#define _VA_TYPES_WITH_ARGS_2(type, ...) type _arg2, _VA_TYPES_WITH_ARGS_1(__VA_ARGS__)
#define _VA_TYPES_WITH_ARGS_3(type, ...) type _arg3, _VA_TYPES_WITH_ARGS_2(__VA_ARGS__)
// etc
它基本上为每个参数附加_argK。
例子:
VA_TYPES_WITH_ARGS(int, bool, float)
将扩展为
int _arg3, bool _arg2, float _arg1
任何帮助将不胜感激。
相关的预处理器问题:
【问题讨论】:
-
VC++ 在涉及到 C99 时是高度瘫痪的。您可以在 Boost.Preprocessor 中到处看到解决方法。无论如何,如果我没记错的话,你可以使用 Boost 的
BOOST_PP_ENUM宏来做你想做的事情。 -
@chris 但是 VC++ 确实针对 C++11,它提供了与 C99 wrt 可变参数宏和空宏参数相同的功能。至少,如果某些有效的 C++11 不能在 VC++ 中工作,那么 VC++ 很有可能会被修复以使其工作。确实,C99 并非如此。 :)
-
@hvd,目标和实现是完全不同的事情。看看所有出现的可变参数模板问题。无论如何,C99 和 C++11 之间的预处理器是相同的,只是减去了一些较小的东西,例如
::,不是吗? -
@chris 哦,当然,我没有对此提出异议,并修改了我之前的评论以更清楚地说明我的意思。
-
顺便说一句,你使用的是reserved identifiers。
标签: c++ gcc visual-c++ macros c-preprocessor