我见过的要求上可变参数的变化的几个问题FOR_EACH
宏。 然而不幸的是提供的答案是用VC ++ 10不兼容由于传递到另一个宏时将其扩大__VA_ARGS __作为一个参数。 请有人能提供一个C ++ 11兼容的(因而向前兼容)版本仍然与VC ++ 10的工作。 也许使用被经常提到的“解决办法”, #define EXPAND(x) x
,但是我不知道在哪里把这个为了得到,例如,后期广义部分这个答案在VC工作++ 10。
为了澄清,预期的行为是FOR_EACH(x, a, b, ...)
以产生x(a) x(b), ...
,其中x是另一个宏。
现在已经掌握了VC ++编译器10臭虫作品究竟如何,我能想出这样一个宏自己的基础上,后期这个答案 。
#define EXPAND(x) x
#define FOR_EACH_1(what, x, ...) what(x)
#define FOR_EACH_2(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_1(what, __VA_ARGS__))
#define FOR_EACH_3(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_2(what, __VA_ARGS__))
#define FOR_EACH_4(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_3(what, __VA_ARGS__))
#define FOR_EACH_5(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_4(what, __VA_ARGS__))
#define FOR_EACH_6(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_5(what, __VA_ARGS__))
#define FOR_EACH_7(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_6(what, __VA_ARGS__))
#define FOR_EACH_8(what, x, ...)\
what(x);\
EXPAND(FOR_EACH_7(what, __VA_ARGS__))
#define FOR_EACH_NARG(...) FOR_EACH_NARG_(__VA_ARGS__, FOR_EACH_RSEQ_N())
#define FOR_EACH_NARG_(...) EXPAND(FOR_EACH_ARG_N(__VA_ARGS__))
#define FOR_EACH_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
#define FOR_EACH_RSEQ_N() 8, 7, 6, 5, 4, 3, 2, 1, 0
#define CONCATENATE(x,y) x##y
#define FOR_EACH_(N, what, ...) EXPAND(CONCATENATE(FOR_EACH_, N)(what, __VA_ARGS__))
#define FOR_EACH(what, ...) FOR_EACH_(FOR_EACH_NARG(__VA_ARGS__), what, __VA_ARGS__)
实例:
#define callMember(o, f) o.f();
#define callMember_o(f) callMember(o, f)
FOR_EACH(callMember_o, doSomething, doSomethingElse);
是相同的
o.doSomething(); o.doSomethingElse();
该解决方案是在链接的答案相似,不同的是在零长度可变参数的参数列表FOR_EACH(what, x, ...)
当一个元素被称为造成虚假的逗号,让FOR_EACH_NARG算2个参数,而不是1周的说法,并且EXPAND
用于宏替代方法。
在VC 10的错误是,如果__VA_ARGS__
被传递到宏可变参数的宏的定义范围内,它被代入宏后,评价,引起多逗号分隔参数被作为一个处理。 为了解决这个问题,你必须延迟参数的评估后才__VA_ARGS__
被取代,在包装宏调用EXPAND
,迫使宏调用被评价为一个字符串,代__VA_ARGS__
这样做。 只有在取代进入EXPAND
是调用的宏,通过该点的可变参数已经被取代。
PS我将不胜感激,如果任何人都可以提出一个方法用于生产紧凑FOR_EACH_N
宏更大的价值N
。