从 0 开始讲透 C++ Lambda(对标 Java)
在写 C 多线程或 STL 时经常会看到这样的代码std::thread t([]{ std::cout Hello C Thread\n; });很多人第一反应这 [] 是什么为什么和 Java 不一样一、先给结论先建立整体认知C lambda 一个“匿名函数对象”不是普通函数 对标 JavaJava () - {} C []() {} 最大区别C 多了一个 []捕获外部变量二、lambda 到底是什么最简单理解[] { std::cout Hello\n; }就是一个没有名字的函数等价普通函数void func() { std::cout Hello\n; }区别lambda 可以“现场写”不用起名字三、完整结构必须掌握[capture](params) { body }各部分含义部分作用[]捕获外部变量C特有()参数和函数一样{}函数体四、params 是什么 就是普通函数参数[](int x) { std::cout x; } 调用auto f [](int x) { std::cout x; }; f(10); 对标 Java(x) - System.out.println(x);五、capture 是什么核心区别 capture 用来解决一个问题函数内部能不能用外部变量❌ 不写 captureint a 10; auto f [] { std::cout a; // ❌ 编译报错 };✅ 正确写法auto f [a] { std::cout a; }; 含义把 a 拷贝进 lambda六、capture 常用写法记这几个就够[] 不捕获 [a] 值捕获 [a] 引用捕获 [] 全部值捕获 [] 全部引用捕获七、capture vs params很多人会混一句话区分capture 外部变量上下文params 调用参数输入示例int a 10; auto f [a](int x) { return a x; }; 含义a → 外部带进来 x → 调用时传进来八、为什么 C 比 Java 多一个 []Javaint a 10; Runnable r () - { System.out.println(a); }; Java 默认可以使用外部变量但必须 finalCint a 10; auto f [] { std::cout a; // ❌ }; C 默认不能访问外部变量 必须显式声明[a] { ... } 设计原因更明确控制变量生命周期和拷贝方式九、lambda 本质是什么关键突破 lambda 不是函数而是一个类对象等价写法auto f [] { std::cout Hello\n; }; 实际类似struct Lambda { void operator()() const { std::cout Hello\n; } }; 所以 f(); // 调用 operator() 这叫函数对象functor十、为什么 thread / STL 都能用 lambda因为lambda 可调用对象 所以可以传给std::threadstd::sortstd::for_each示例std::sort(v.begin(), v.end(), [](int a, int b) { return a b; });十一、总结笔记版C lambda [capture](params) { body } 本质 - 匿名函数对象类 - 重载 operator() capture - 外部变量 - 控制拷贝 or 引用 params - 函数参数 区别 capture 外部上下文 params 输入参数 对比 Java Java () - {} C []() {}多了捕获十二、你现在掌握了什么非常关键你已经打通✔ lambda结构✔ capture机制✔ params✔ 与Java对比✔ 本质类 operator() 这意味着你已经进入现代 C并发 STL 回调核心能力区下一篇《C Lambda 进阶为什么 [] 在线程中会出问题》这个是面试高频 工程坑int a 10; std::thread t([]{ std::cout a; }); 看起来没问题但其实有坑
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2453732.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!