在Visual Studio 2005上,我有一个看起来像这样的宏(已放大!):
#define MY_CALL(FUN, ...) \
if(prepare(x, y)) { \
FUN(__VA_ARGS__); \
}
/**/
只要该函数至少接受一个参数,就可以了。
[当函数接受零个参数时,预处理器“有帮助地”删除“尾随逗号”,展开如下所示:
if(prepare(x y)) { funct(); }
很好,不是吗?
如何修复此宏,以便在Visual C ++(VS 2005)上将其与零__VA_ARGS__
一起使用?
不幸的是,我不再使用Visual C ++(因此无法验证此方法是否有效,但是可以尝试吗?
#define MY_CALL(FUN, ...) \
if(prepare(x, y)) { \
int fail[] = {0,} \
FUN(__VA_ARGS__); \
}
使用gcc 4.2,在这种情况下都允许{0,}
和{0}
,因此,如果逗号被删除还是不被删除,都没有关系。但是,我不确定这是规范中普遍接受的,是常用的扩展还是gcc特定的东西。
如果Visual C ++允许{0,}
语法is,那么这有望解决您的问题(假设我正确理解__VA_ARGS__
之前的最新逗号是被错误删除的内容,无论它在哪里出现在语法中)。
我已经找到一种无需创建任何C ++代码膨胀的方法。只需为自己定义此宏即可:
#define PREVENT_EATING_COMMA_IMPL(x, __VA_ARGS__) __VA_ARGS__
#define PREVENT_EATING_COMMA(...) PREVENT_EATING_COMMA_IMPL(x, __VA_ARGS__)
然后
#define DEFER(...) PREVENT_EATING_COMMA(__VA_ARGS__)
即使您没有在其中传递任何参数,也不会吃逗号,效果很好。在您的示例中,您将__VA_ARGS__
包装在PREVENT_EATING_COMMA(__VA_ARGS__)
中。