You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中编写内联递归Lambda?C++20/23是否有新方案?

C20与C23中的递归Lambda实现方案

针对你提到的C17递归Lambda需要额外传递self参数的痛点,C20和C++23确实提供了更简洁的实现方式,同时也能解决你关心的内联优化问题:

C++20的实现方式

在C++20中,你可以通过两种方式实现无需显式传递self的递归Lambda:

方式一:借助std::function

这种写法无需额外传递self,代码更简洁,示例如下:

#include <functional>

int main() {
    std::function<void(int)> dfs;
    dfs = [&](int x) -> void {
        if (x >= 5) return;
        // 直接调用自身
        dfs(x + 1);
    };
    dfs(0);
}

虽然std::function存在类型擦除的理论开销,但开启优化(如-O2)后,GCC、Clang、MSVC等主流编译器都会尽可能消除这部分开销并完成内联。

方式二:手动实现Y组合子

如果你想完全避免类型擦除,可以用Y组合子实现零开销的递归Lambda,示例如下:

template<typename F>
struct YCombinator {
    F f;
    template<typename... Args>
    decltype(auto) operator()(Args&&... args) {
        return f(*this, std::forward<Args>(args)...);
    }
};

template<typename F>
YCombinator(F) -> YCombinator<F>;

int main() {
    auto dfs = YCombinator{[&](auto& self, int x) -> void {
        if (x >= 5) return;
        self(x + 1);
    }};
    dfs(0);
}

这种写法没有类型擦除的额外开销,编译器更容易进行内联优化,性能表现和C++17的self传递方案相当甚至更优。

C++23的原生递归Lambda

C++23直接支持原生递归Lambda,这是最简洁的实现方式,无需任何额外工具,示例如下:

int main() {
    auto dfs = [&](int x) -> void {
        if (x >= 5) return;
        // 直接调用自身,无需额外参数或包装
        dfs(x + 1);
    };
    dfs(0);
}

这种语法完全消除了C++17方案中传递self的繁琐,而且因为是原生语法,编译器对这种递归模式的识别更直接,开启优化后几乎都能轻松完成内联,不会有性能损耗。

关于内联的补充说明

你担心的C17方案内联问题,实际上主流编译器在开启-O2及以上优化级别时,都能识别self传递的递归模式并完成内联。而C23的原生递归Lambda因为语法更贴合编译器的优化逻辑,内联的可靠性和效率会更高。

内容的提问来源于stack exchange,提问作者Junhui Zhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:22:46