首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过__VA_OPT__实现递归宏

通过__VA_OPT__实现递归宏
EN

Stack Overflow用户
提问于 2018-07-04 05:14:05
回答 1查看 2K关注 0票数 1

__VA_OPT__编写递归宏合法吗?

GCC和Clang似乎没有递归地替换,但我不确定这是否有意(因为__VA_OPT__支持是最近的)。

C++规范(第19.3.1/3节:__VA_OPT__): 否则,替换由内容扩展结果作为当前类似于函数的宏的替换列表,然后再重新扫描和进一步替换

上面突出显示的部分是否意味着不可能递归?

例如,要添加各种宏参数的列表:

代码语言:javascript
运行
复制
#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

代码语言:javascript
运行
复制
// NOTE: Below is the output from g++ -E
int main(int argc, char const* const argv[])
 {
  return 1 + 2 RECURSE(3, 4);
 }

注意:如果可能的话,可以很容易地编写更复杂的各种宏,比如级联,因为您可以从__VA_OPT__创建一个自定义的__VA_OPT__,它允许为1和2+参数提供完全独立的代码。

EN

回答 1

Stack Overflow用户

发布于 2021-06-07 21:22:29

答案是肯定的!在某种程度上,您已经可以使用在C中有递归宏,您可以在C++20中这样做,而__VA_OPT__使一些事情变得更好。

下面是您可以做的事情的一个例子(附有解释):定义一个FOR_EACH宏,它将宏应用于一堆参数,比__VA_OPT__之前必须做的可怕的事情要好得多

代码语言:javascript
运行
复制
#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)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51166178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档