当前位置: 首页 > news >正文

昆明做网站那家好建设网站商城

昆明做网站那家好,建设网站商城,浙江信息港查询三类证书,建设展示类网站的意义核心问题&#xff1a;匿名函数没有“名字”常规的递归函数可以调用自己&#xff0c;是因为它有自己的名字&#xff1a;int factorial(int n) {if (n < 1) return 1;return n * factorial(n - 1); // <-- 通过名字 factorial 调用自己 }但 Lambda 表达式是匿名的&#xff…

核心问题:匿名函数没有“名字”

常规的递归函数可以调用自己,是因为它有自己的名字:

int factorial(int n) {if (n <= 1) return 1;return n * factorial(n - 1); // <-- 通过名字 'factorial' 调用自己
}

但 Lambda 表达式是匿名的,在它的函数体内部,它不知道自己的“名字”是什么,因此无法直接引用自己。

auto factorial_lambda = [](int n) {if (n <= 1) return 1;// return n * ???(n - 1); // <-- ??? 这里该写什么?
};

为了解决这个问题,我们需要一种方法让 Lambda 能够“找到”并调用它自身。主要有以下几种方法,你需要根据你的 C++ 标准版本和具体场景来选择。


方法一:使用 std::function (C++11 及以上)

这是最经典、最通用的方法。思路是先创建一个 std::function 对象,然后让 Lambda 按引用捕获这个 std::function 对象本身。

#include <iostream>
#include <functional>int main() {// 1. 声明一个 std::function 对象来包裹 Lambdastd::function<int(int)> factorial;// 2. 定义 Lambda,并【按引用】捕获 factorialfactorial = [&factorial](int n) -> int {if (n <= 1) {return 1;} else {// 3. 通过捕获到的 factorial 对象实现递归调用return n * factorial(n - 1);}};std::cout << factorial(5) << std::endl; // 输出 120return 0;
}
⚠️ 注意事项:

  1. 必须按引用捕获 ([&factorial]):这是此方法最关键的一点!如果你按值捕获 ([=][factorial]),在 Lambda 被创建时,它会试图复制 factorial 对象,但此时 factorial 自身还没有被赋值(它正在被定义的过程中),这会导致未定义行为(通常是程序崩溃)。按引用捕获则没有这个问题,因为它捕获的是 factorial 这个“容器”的引用,而不是它当时的内容。

  2. 性能开销std::function 为了通用性,使用了类型擦除 (Type Erasure) 技术,可能会有微小的性能开销(例如虚函数调用或堆分配)。对于性能极其敏感的场景,这可能不是最佳选择。


方法二:使用泛型 Lambda (C++14 及以上)

这是一种更现代、更高效的方法,它巧妙地利用了泛型 Lambda 的特性,将 Lambda 自身作为参数传递给自己。

#include <iostream>int main() {// 1. 定义一个泛型 Lambda,第一个参数用于接收“自己”auto factorial = [](auto&& self, int n) -> int { // 这里使用的是转发引用,根据传入的函数自动推导。if (n <= 1) {return 1;} else {// 2. 通过传入的 self 参数实现递归return n * self(self, n - 1);}};// 3. 首次调用时,需要将 Lambda 对象自身作为第一个参数传入std::cout << factorial(factorial, 5) << std::endl; // 输出 120return 0;
}

这里的 auto&& self 是一个通用引用(forwarding reference),可以接受任何类型的 self 参数,非常灵活。

⚠️ 注意事项:

  1. 调用形式略显奇怪:第一次调用 factorial(factorial, 5) 和递归调用 self(self, n-1) 的形式需要习惯一下。

  2. 高性能:这种方法避免了 std::function 的开销,编译器可以更好地进行内联和优化,性能几乎等同于普通的递归函数。


方法三:使用 deducing this (C++23 及以上)

C++23 带来了一个终极解决方案:deducing this。它允许 Lambda 显式地将自己的闭包对象(closure object)作为参数,从而可以直接引用自己,语法非常优雅。

#include <iostream>int main() {// 1. 使用 `this auto&&` 将 Lambda 自身作为参数auto factorial = [](this auto&& self, int n) -> int { if (n <= 1) {return 1;} else {// 2. 直接调用 self 即可,无需再传递它return n * self(n - 1);}};std::cout << factorial(5) << std::endl; // 输出 120return 0;
}

⚠️ 注意事项:

  1. 需要 C++23 支持:这是最新的标准,你需要一个支持 C++23 的编译器(例如 GCC 12+, Clang 15+)。

  2. 最优雅的方案:它的调用方式 factorial(5)self(n-1) 与普通函数完全一致,是未来编写递归 Lambda 的最佳方式。

总结与建议

方法

核心思想

优点

缺点

适用场景

std::function

按引用捕获 std::function 包装器

✅ 通用,C++11即可用
✅ 调用语法自然 f(5)

⚠️ 必须按引用捕获
❌ 有轻微性能开销

兼容旧标准 (C++11) 或需要将 Lambda 存入 std::function 容器的场合。

泛型 Lambda

将自身作为参数传递

✅ 高性能,无额外开销
✅ C++14即可用

❌ 调用和递归语法稍显繁琐 f(f, 5)

性能敏感,且使用 C++14/17/20 的现代 C++ 项目。(当前主流推荐)

deducing this

语言层面直接支持自引用

✅ 语法最简洁、最优雅
✅ 高性能

❌ 需要 C++23 编译器支持

使用 C++23 及以上标准的项目。(未来最佳实践)

一句话总结:

写递归 Lambda 时,首要记住它不能直接调用自己。然后根据你的 C++ 版本,优先选择 C++23 的 deducing this,其次是 C++14 的泛型 Lambda,最后才是 C++11 的 std::function 方法(并牢记必须按引用捕获)。

http://www.dtcms.com/a/428830.html

相关文章:

  • seo的网站建设建站基础:wordpress安装教程图解 - 天缘博客
  • centos 7.2 做网站婚礼请柬电子版免费制作app
  • 宜兴网站建设公司qq推广网站
  • 网站建设 设备推广app软件
  • 【动态规划:子数组/子串系列】单词拆分 环绕字符串中唯⼀的子字符串
  • 做网站服务器要什么系统推广怎么推广
  • qq网站登录北京网站优化推广分析
  • CNN的可视化:特征图与卷积核可视化方法(代码实现)
  • 读写RPLMN等APDU log显示为FF FF FF……问题研究
  • CKAD-CN 考试知识点分享(8) 升级与回滚
  • 网站建设公司该如何选择服务称赞的项目管理平台
  • 哪里做网站比较快wordpress主题 视频
  • 网站建设实训总结范文品牌市场营销策略
  • 网站界面设计软件网站备案去哪注销
  • 网页设计感十足的网站移动开发软件
  • LangChain 中 “附加 OpenAI 函数” 和 “附加 OpenAI 工具”
  • 山东住房和城乡建设厅网站登陆平面设计必学软件
  • 凡客建站官网登录入口Wordpress仿制网站
  • 网站开发技术的发展开发者门户网站是什么意思
  • GIS 相关基础知识
  • 陕西有色建设有限公司官方网站花生壳动态域名做网站
  • 企业网站seo平台不孕不育网站建设总结
  • 做短连接的网站织梦门户网站
  • 怎么做网站流量统计wordpress值得买模板
  • 【DRAM存储器五十八】LPDDR5介绍--IO结构,VREF和ODT有什么关系?
  • 增塑剂网站建设wordpress google
  • 什么是网站的主页seo优化排名工具
  • 网站域名怎么购买大连在哪个城市
  • 新电脑(包含联想电脑)访问正常的系统加载不出页面,但是网络telnet又是通畅的(PG数据库连接public模式下能看到表及数据,其他模式下的表和数据看不了)
  • 中为网站建设重庆cms建站模板