Preprocessor variadic FOR_EACH macro compatible with MSVC++10(与 MSVC++10 兼容的预处理器可变参数 FOR_EACH 宏)
问题描述
我看到了一些要求对可变参数 澄清一下,预期行为是 现在已经准确掌握了 VC++10 编译器错误的工作原理,我能够根据 示例用法: 与 此解决方案与链接答案中的解决方案类似,不同之处在于 VC++10 中的 bug 是,如果 附言如果有人可以建议一种紧凑地生成 I've seen a few questions asking for a variation on a variadic To clarify, the intended behaviour is for Having now grasped exactly how the VC++10 compiler bug works, I was able to come up with such a macro myself, based on the latter part of this answer. Example usage: is the same as This solution is similar to that in the linked answer, except that the zero length variadic argument list in The bug in VC++10 is that if P.S. I would be grateful if anyone can suggest a method for compactly producing 这篇关于与 MSVC++10 兼容的预处理器可变参数 FOR_EACH 宏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!FOR_EACH 宏进行变体的问题.然而不幸的是,提供的答案与 VC++10 不兼容,因为它在传递给另一个宏时将 __VA_ARGS __ 扩展为一个参数.请有人提供仍然适用于 VC++10 的 C++11 兼容(因此向前兼容)版本.也许使用经常提到的解决方法",
#define EXPAND(x) x
,但是我不知道把它放在哪里以获得,例如,这个答案适用于 VC++10.FOR_EACH(x, a, b, ...)
产生 x(a) x(b), ...
,其中 x 是另一个宏.#define EXPAND(x) x#define FOR_EACH_1(what, x, ...) what(x)#define FOR_EACH_2(what, x, ...)什么(x);扩展(FOR_EACH_1(什么,__VA_ARGS__))#define FOR_EACH_3(what, x, ...)什么(x);扩展(FOR_EACH_2(什么,__VA_ARGS__))#define FOR_EACH_4(what, x, ...)什么(x);扩展(FOR_EACH_3(什么,__VA_ARGS__))#define FOR_EACH_5(what, x, ...)什么(x);扩展(FOR_EACH_4(什么,__VA_ARGS__))#define FOR_EACH_6(what, x, ...)什么(x);扩展(FOR_EACH_5(什么,__VA_ARGS__))#define FOR_EACH_7(what, x, ...)什么(x);扩展(FOR_EACH_6(什么,__VA_ARGS__))#define FOR_EACH_8(what, x, ...)什么(x);扩展(FOR_EACH_7(什么,__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 连接(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
宏解决方法.__VA_ARGS__
被传递给可变参数宏定义内的宏,它会在替换到宏后被评估,导致多个逗号分隔的参数被视为一.要解决这个问题,您必须延迟参数评估,直到替换 __VA_ARGS__
之后,将宏调用包装在 EXPAND
中,强制将宏调用评估为字符串,替换 __VA_ARGS__
代码>__VA_ARGS__ 这样做.只有在替换到 EXPAND
之后才调用宏,此时可变参数已经被替换.FOR_EACH_N
宏的方法,以获取更大的 N
值,我将不胜感激.FOR_EACH
macro. However unfortunately the answers provided are incompatible with VC++10 due to it expanding __VA_ARGS __ as one argument when passed to another macro. Please could someone provide a C++11 compliant (thus forward-compatible) version that still works with VC++10. Perhaps using the "workaround" that is often mentioned, #define EXPAND(x) x
, however I don't know where to put this in order to get, for example, the latter generalised part of this answer to work in VC++10.FOR_EACH(x, a, b, ...)
to produce x(a) x(b), ...
, where x is another macro.#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, ...)
when called with one element caused a spurious comma that makes FOR_EACH_NARG count 2 arguments instead of 1 argument, and the EXPAND
macro workaround is used.__VA_ARGS__
is passed to a macro within the definition of a variadic macro, it is evaluated after substitution into the macro, causing multiple comma separated arguments to be treated as one. To get around this you must delay argument evaluation until after __VA_ARGS__
is substituted, by wrapping the macro call in EXPAND
, forcing the macro call to be evaluated as a string, substituting __VA_ARGS__
to do so. Only after the substitution into EXPAND
is the macro called, by which point the variadic arguments are already substituted.FOR_EACH_N
macros for much larger values of N
.
本文标题为:与 MSVC++10 兼容的预处理器可变参数 FOR_EACH 宏
基础教程推荐
- 从 std::cin 读取密码 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01