news 2026/7/25 16:56:00

C++ lambda 匿名函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C++ lambda 匿名函数

C++ lambda 匿名函数

什么是 lambda 表达式Lambda 表达式是 C++11 引入的一种匿名函数语法,允许我们在代码中直接定义函数对象而不必显式声明一个类或函数。它极大地简化了回调、算法和事件处理等场景的代码编写。Lambda 的基本语法如下:cpp[capture](parameters) -> return_type { body }其中:-capture:捕获列表,定义如何从外部作用域访问变量-parameters:参数列表-return_type:返回类型(可省略,编译器可自动推导)-body:函数体## 基础示例:最简单的 lambda让我们从一个最简单的 lambda 开始,它不捕获任何外部变量,只是执行一个简单的输出。cpp#include <iostream>int main() { // 最简单的 lambda:不捕获任何变量,不接受参数,无返回值 auto hello = []() { std::cout << "Hello from lambda!" << std::endl; }; hello(); // 调用 lambda // 带参数的 lambda auto add = [](int a, int b) -> int { return a + b; }; int result = add(3, 4); std::cout << "3 + 4 = " << result << std::endl; // 更简洁的写法:自动推导返回类型 auto multiply = [](int a, int b) { return a * b; }; std::cout << "5 * 6 = " << multiply(5, 6) << std::endl; return 0;}输出:Hello from lambda!3 + 4 = 75 * 6 = 30## 捕获机制详解Lambda 的捕获机制是它最强大的特性之一。通过捕获列表,lambda 可以访问和使用定义它的作用域中的变量。cpp#include <iostream>#include <vector>#include <algorithm>int main() { // ===== 值捕获 ===== int x = 10; int y = 20; // 按值捕获 x 和 y auto sum = [x, y]() { return x + y; }; std::cout << "Sum with capture: " << sum() << std::endl; // 输出 30 // 修改捕获的变量:注意!按值捕获的变量在 lambda 内部是 const 的 // 需要加上 mutable 关键字才能修改 auto mutable_capture = [x]() mutable { x += 5; // 现在可以修改了,但只影响 lambda 内部的副本 return x; }; std::cout << "After mutable: " << mutable_capture() << std::endl; // 输出 15 std::cout << "Outside x still: " << x << std::endl; // 输出 10 // ===== 引用捕获 ===== int counter = 0; auto increment = [&counter]() { counter++; // 直接修改外部变量 }; increment(); increment(); increment(); std::cout << "Counter after 3 increments: " << counter << std::endl; // 输出 3 // ===== 混合捕获 ===== int a = 1, b = 2, c = 3; auto mixed = [a, &b, &c]() { // a 是值捕获(只读),b 和 c 是引用捕获(可修改) b += a; c += a; }; mixed(); std::cout << "a=" << a << ", b=" << b << ", c=" << c << std::endl; // a=1, b=3, c=4 // ===== 默认捕获 ===== int val = 42; auto capture_all_by_value = [=]() { // [=] 捕获所有外部变量为值 return val; }; auto capture_all_by_reference = [&]() { // [&] 捕获所有外部变量为引用 val = 100; }; capture_all_by_reference(); std::cout << "After reference capture: " << val << std::endl; // 输出 100 // ===== 实际应用:与 STL 算法配合 ===== std::vector<int> numbers = {1, 5, 3, 8, 2, 7, 4}; int threshold = 4; // 使用 lambda 作为谓词 auto count = std::count_if(numbers.begin(), numbers.end(), [threshold](int n) { return n > threshold; }); std::cout << "Numbers > " << threshold << ": " << count << std::endl; // 输出 3 // 使用 lambda 进行排序 std::vector<int> to_sort = {9, 3, 7, 1, 5}; std::sort(to_sort.begin(), to_sort.end(), [](int a, int b) { return a > b; // 降序排序 }); std::cout << "Sorted descending: "; for (int n : to_sort) { std::cout << n << " "; } std::cout << std::endl; return 0;}## 高级用法:泛型 lambda 与状态保持C++14 引入了泛型 lambda,允许使用 auto 参数类型。同时,lambda 对象可以保持状态。cpp#include <iostream>#include <functional>#include <vector>#include <algorithm>#include <string>int main() { // ===== 泛型 lambda (C++14) ===== auto generic_lambda = [](auto a, auto b) { return a + b; }; std::cout << "Int addition: " << generic_lambda(10, 20) << std::endl; // 输出 30 std::cout << "Double addition: " << generic_lambda(3.14, 2.86) << std::endl; // 输出 6.0 std::cout << "String concatenation: " << generic_lambda(std::string("Hello "), "World") << std::endl; // 输出 Hello World // ===== 保持状态的 lambda ===== // 创建一个计数器,每次调用递增 auto make_counter = []() { int count = 0; return [count]() mutable { return ++count; }; }; auto counter1 = make_counter(); auto counter2 = make_counter(); std::cout << "Counter1: "; for (int i = 0; i < 5; ++i) { std::cout << counter1() << " "; // 输出 1 2 3 4 5 } std::cout << std::endl; std::cout << "Counter2: "; for (int i = 0; i < 3; ++i) { std::cout << counter2() << " "; // 输出 1 2 3 } std::cout << std::endl; // ===== 使用 std::function 存储 lambda ===== std::function<int(int, int)> func; func = [](int a, int b) { return a + b; }; std::cout << "Using std::function: " << func(10, 20) << std::endl; // 可以替换为另一个 lambda func = [](int a, int b) { return a * b; }; std::cout << "After reassignment: " << func(10, 20) << std::endl; // ===== 实际应用:自定义比较器 ===== std::vector<std::string> names = {"Alice", "Bob", "Charlie", "David", "Eve"}; // 按字符串长度排序 std::sort(names.begin(), names.end(), [](const std::string& a, const std::string& b) { return a.length() < b.length(); }); std::cout << "Sorted by length: "; for (const auto& name : names) { std::cout << name << " "; } std::cout << std::endl; // ===== 递归 lambda (使用 std::function) ===== std::function<int(int)> factorial = [&factorial](int n) -> int { return n <= 1 ? 1 : n * factorial(n - 1); }; std::cout << "Factorial of 5: " << factorial(5) << std::endl; // 输出 120 // ===== 使用 lambda 进行延迟计算 ===== auto lazy_add = [](int a, int b) { return [a, b]() { return a + b; }; }; auto delayed = lazy_add(100, 200); // 此时还没有计算 std::cout << "Delayed computation: " << delayed() << std::endl; // 输出 300 return 0;}## 性能与注意事项1.内联优化:Lambda 本质上是函数对象,编译器通常可以将其内联展开,性能优于函数指针。2.捕获开销: - 值捕获:复制变量,可能产生开销 - 引用捕获:没有复制开销,但需要注意生命周期3.生命周期问题:不要返回或存储引用捕获的 lambda 超出原始变量的生命周期。4.mutable 关键字:只有在需要修改值捕获的变量时才使用 mutable。5.默认捕获:谨慎使用[=][&],最好明确列出需要捕获的变量,以提高代码可读性。## 总结C++ lambda 匿名函数是现代 C++ 编程中不可或缺的工具。它提供了:-简洁性:将函数定义和使用紧密耦合,减少代码跳转-灵活性:支持值捕获、引用捕获、默认捕获等多种方式-强大功能:可以与 STL 算法、回调函数、事件处理等完美配合-性能优势:编译器优化良好,通常不会比手写函数对象差在实际开发中,lambda 常用于:- STL 算法的自定义操作(排序、查找、变换等)- 回调函数和事件处理器- 延迟计算和函数工厂- 替代短小的辅助函数掌握 lambda 是成为高效 C++ 开发者的重要一步。通过合理使用 lambda,可以写出更清晰、更维护的代码。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/25 16:54:42

终极指南:3步解决Blender导入MMD模型的常见难题

终极指南&#xff1a;3步解决Blender导入MMD模型的常见难题 【免费下载链接】blender_mmd_tools MMD Tools is a blender addon for importing/exporting Models and Motions of MikuMikuDance. 项目地址: https://gitcode.com/gh_mirrors/bl/blender_mmd_tools 你是否曾…

作者头像 李华
网站建设 2026/7/25 16:54:22

《末行手記》深度解析:高智商犯罪剧的观看方法论与心理操控剖析

1. 先搞清楚这部剧到底在讲什么,以及为什么值得看 《末行手記》是近期在流媒体平台上线的一部韩国剧集,从标题和网络讨论来看,它核心探讨的是一个高智商犯罪与心理操控的故事。教授被自己的天才学生一步步操控,最终走向犯罪的深渊,这个设定本身就充满了戏剧张力和人性拷问…

作者头像 李华
网站建设 2026/7/25 16:52:10

边缘计算与AI融合:实时目标检测的优化实践

1. 边缘计算与AI原生的技术融合趋势在智能摄像头、工业质检机器人、自动驾驶等场景中&#xff0c;传统云计算架构的延迟和带宽限制日益凸显。去年参与某智慧工厂项目时&#xff0c;产线质检系统因网络抖动导致200ms的检测延迟&#xff0c;直接影响了流水线节拍。这促使我们转向…

作者头像 李华
网站建设 2026/7/25 16:50:51

吴恩达提示工程实战教程:从核心原则到API集成,解锁大模型应用开发

如果你正在寻找一套系统、完整且能直接上手的提示工程教程,那么吴恩达教授在B站发布的《提示词工程》课程可能就是你要找的答案。这套教程并非简单的概念讲解,而是从大模型入门到进阶,覆盖了提示工程的核心原则、高级技巧以及实际应用,并附带了课件和代码,旨在帮助开发者、…

作者头像 李华
网站建设 2026/7/25 16:50:16

智能全自动清理猫砂盆猫咪存在检测方案设计

有没有想过&#xff0c;智能猫砂盆要做到猫离即清&#xff0c;最难的一关其实藏在看不见的地方。市面上的产品大多卡在同一个问题上&#xff1a;猫走进盆里安静蹲着的时候&#xff0c;传感器却判断不了它还在不在。一旦漏判&#xff0c;清理机构提前启动&#xff0c;后果不堪设…

作者头像 李华
网站建设 2026/7/25 16:42:39

AI Agent 实战指南:从零部署 Hermes Agent,构建可进化的智能助手

如果你正在寻找一个能真正理解你、能帮你处理日常任务、还能从经验中不断学习的 AI 助手,而不是一个只会回答问题的聊天机器人,那么 Hermes Agent 可能是你一直在等待的答案。它不仅仅是一个工具,更像是一个能与你共同成长的数字伙伴。但问题来了:市面上 AI Agent 项目层出…

作者头像 李华