编写递归宏是否合法__VA_OPT__
?
GCC 和 Clang 似乎没有递归替换,但我不确定它是否是故意的(如__VA_OPT__
支持是最近才出现的)。
C++ 规范(§19.3.1/3:__VA_OPT__
):
否则,替换由扩展的结果组成
内容作为当前类函数宏的替换列表在重新扫描和进一步更换之前
上面突出显示的部分是否意味着递归是不可能的?
例如,要添加可变宏参数列表:
#define RECURSE(mFIRST, ...) + mFIRST __VA_OPT__(RECURSE(__VA_ARGS__))
int main(int argc, char const* const argv[])
{
return 1 RECURSE(2, 3, 4);
// Expected result: "return 1 + 2 + 3 + 4;"
}
GCC 和 Clang 都会生成RECURSE
在他们的后预处理中。
// NOTE: Below is the output from g++ -E
int main(int argc, char const* const argv[])
{
return 1 + 2 RECURSE(3, 4);
}
注意:如果可能的话,可以相当容易地编写更复杂的可变参数宏,例如连接,因为您可以创建自定义__VA_NO_OPT__
from __VA_OPT__
,它允许您为 1 个和 2 个以上参数提供完全独立的代码。
答案是肯定的!只要你已经可以C 中有递归宏 https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms,你可以在 C++20 中做到这一点并且__VA_OPT__
让一些事情变得更加美好。
Here's 一个例子(带解释) https://www.scs.stanford.edu/%7Edm/blog/va-opt.html你可以做什么:定义一个FOR_EACH
将宏应用于一堆参数的宏,比您之前必须做的可怕事情要好得多__VA_OPT__
:
#define PARENS () // Note space before (), so object-like macro
#define EXPAND(arg) EXPAND1(EXPAND1(EXPAND1(EXPAND1(arg))))
#define EXPAND1(arg) EXPAND2(EXPAND2(EXPAND2(EXPAND2(arg))))
#define EXPAND2(arg) EXPAND3(EXPAND3(EXPAND3(EXPAND3(arg))))
#define EXPAND3(arg) EXPAND4(EXPAND4(EXPAND4(EXPAND4(arg))))
#define EXPAND4(arg) arg
#define FOR_EACH(macro, ...) \
__VA_OPT__(EXPAND(FOR_EACH_HELPER(macro, __VA_ARGS__)))
#define FOR_EACH_HELPER(macro, a1, ...) \
macro(a1) \
__VA_OPT__(FOR_EACH_AGAIN PARENS (macro, __VA_ARGS__))
#define FOR_EACH_AGAIN() FOR_EACH_HELPER
FOR_EACH(F, a, b, c, 1, 2, 3) // => F(a) F(b) F(c) F(1) F(2) F(3)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)