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

C++ 新特性详解:Lambda 表达式全解析(含实战案例)

🚀 C++ 新特性详解:Lambda 表达式全解析(含实战案例)
📅 更新时间:2025年6月4日
🏷️ 标签:C++11 | Lambda表达式 | 匿名函数 | STL | 现代C++

文章目录

  • 前言
  • 🧠 一、Lambda 表达式简介
    • 📌 语法结构如下:
  • 📍 二、为什么需要 Lambda?
    • 示例:
      • 普通写法
      • 外部Lambda写法
      • 内部Lambda写法
  • 🔍 三、Lambda 捕获方式详解(重点)
    • [ ] 不捕获
      • 正确示例
      • 错误示例
    • [=] 按值捕获所有外部变量
      • 正确示例
      • 错误示例
    • [&] 按引用捕获所有外部变量
    • [ x ] 按值的方式 仅 捕获x变量
      • 正确示例
      • 错误示例
    • [ &x ] 按引用的方式 仅 捕获x变量
      • 正确示例
      • 错误示例
    • ⚠️注意:
      • mutable用法!!!!
      • 为什么要用mutable而不是直接按引用捕获
  • ✅四、Lambda 表达式的优势总结
  • 总结


前言

提示:这里可以添加本文要记录的大概内容:

在 C++ 编程中,Lambda 表达式是一种强大而灵活的工具,它让我们能够以简洁的方式定义匿名函数。自 C++11 引入以来,Lambda 表达式不仅简化了代码,还为函数式编程提供了更多可能性。无论是在快速实现小型功能、处理容器操作,还是作为回调函数,Lambda 都能让你的代码更优雅、更高效。 在本文中,我将通过简单的示例,带你了解 Lambda 表达式的基本语法、用法以及实际应用场景,帮助你快速上手这一现代 C++ 的核心特性!


提示:以下是本篇文章正文内容,下面案例可供参考

🧠 一、Lambda 表达式简介

Lambda 表达式是 C++11 引入的一种 轻量级函数对象 写法,也可以理解为 匿名函数。

它的出现极大地提升了代码的 简洁性 和 灵活性,尤其适合在算法、回调函数、STL 中的临时函数处理

📌 语法结构如下:

[捕获列表](参数列表) -> 返回类型 {函数体
};其中:[]:捕获外部变量(重点)():定义参数-> 返回类型:可省略{}:函数体

📍 二、为什么需要 Lambda?

传统的 C++ 使用函数对象(Functor)或函数指针,但它们在一些局部场景中写法冗长。

示例:

如果我们要对一个vector中的值进行从大到小的排序
普通写法会用sort+自定义cmp函数来进行实现

普通写法

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;bool cmp(int a,int b)
{return a>b;
}   int main()
{vector<int>p={6, 5, 4, 7, 3, 2, 9, 1, 8};sort(p.begin(),p.end(),cmp);for (int i = 0; i < p.size();i++){cout << p[i] << " ";}cout<<endl;return 0;
}输出: 9 8 7 6 5 4 3 2 1

但这样我们在外部写了一个cmp函数,那我们能不能直接在内容进行写呢?
当然可以,不过我先写一份外部的

外部Lambda写法

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;int main()
{vector<int>p={6, 5, 4, 7, 3, 2, 9, 1, 8};auto cmp=[](int a,int b){return a>b;};sort(p.begin(),p.end(),cmp);for (int i = 0; i < p.size();i++){cout << p[i] << " ";}cout<<endl;return 0;}
输出: 9 8 7 6 5 4 3 2 1

我们也可以直接定义在内部

内部Lambda写法

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;int main()
{vector<int>p={6, 5, 4, 7, 3, 2, 9, 1, 8};sort(p.begin(),p.end(),[](int a,int b){return a>b;});for (int i = 0; i < p.size();i++){cout << p[i] << " ";}cout<<endl;return 0;}
输出: 9 8 7 6 5 4 3 2 1

📌 更短、更清晰、不污染命名空间。

🔍 三、Lambda 捕获方式详解(重点)

在这里插入图片描述

[ ] 不捕获

中间不需要写任何东西 因为我们不需要使用外界的东西

正确示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[](){int p=10;cout<<10<<endl;};f();//调用函数freturn 0;
}
输出: 10

错误示例

这里直接调用外部变量x是错误的
因为[ ] 并没有对外部变量进行捕获,相当于这个函数内部是不知道有x这个东西

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[](){int p=x;//错误!!!!!!!!cout<<p<<endl;};f();//调用函数freturn 0;
}

[=] 按值捕获所有外部变量

正确示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[=](){int p=x;cout<<p<<endl;};f();//调用函数freturn 0;
}输出: 10

错误示例

我们是按值进行捕获,所以不能修改变量x的值

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[=](){x++;//!!!!!!!!!错误int p=x;cout<<p<<endl;};f();//调用函数freturn 0;
}

[&] 按引用捕获所有外部变量

此时变量x的值会改变

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[&](){x++;int p=x;cout<<p<<endl;};f();//调用函数freturn 0;
}
输出: 
11
x=11

[ x ] 按值的方式 仅 捕获x变量

正确示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[x](){int p=x;cout<<"p="<<p<<endl;};f();//调用函数freturn 0;
}

错误示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[x](){x++;//错误!!!因为是按值捕获int p=y;//错误!!!没有捕获ycout<<"p="<<p<<endl;};f();//调用函数freturn 0;
}

[ &x ] 按引用的方式 仅 捕获x变量

正确示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[&x](){int p=x;x++;cout<<"p="<<p<<endl;};f();//调用函数fcout<<"x="<<x<<endl;return 0;
}
输出:
p=10
x=11

错误示例

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[&x](){int p=y;//错误!!!!没有捕获ycout<<"p="<<p<<endl;};f();//调用函数freturn 0;
}

⚠️注意:

Lambda 默认是 const 的,不能修改值捕获的变量

若要修改,需加 mutable

mutable用法!!!!

当我们想按值传递,但想在函数体内部修改值,就要用到mutable

#include<iostream>
using namespace std;int main()
{int x=10;int y=20;auto f=[=]()mutable{x++;int p=x;cout<<p<<endl;};f();//调用函数fcout<<"x="<<x<<endl;return 0;
}
输出
11
x=10

这里我们在函数内部对x的值进行了修改,但不会影响外部的
相当于我们生成了一份x的副本在函数中自己任意修改

为什么要用mutable而不是直接按引用捕获

❓既然我想修改变量,为什么不用引用捕获 [&x],而要用值捕获 [x] mutable 呢?
在这里插入图片描述❗所以为什么要用 [x] mutable?
✅ 1. 更安全
引用捕获 [&x] 可能导致:

外部变量生命周期结束,悬空引用

多线程时读写冲突(线程不安全)

而 [x] mutable 是 闭包变量拷贝进来,不依赖外部变量,更安全可靠。

✅ 2. 更有意图表达性(intent clarity)
使用 [x] mutable 表示:

“我只是需要一个可修改的临时副本,不会影响原值”

比如在多线程中,每个线程修改自己的副本变量:

int counter = 0;
std::thread t1([counter]() mutable {for (int i = 0; i < 10; ++i) counter++;std::cout << counter << "\n";
});

✅四、Lambda 表达式的优势总结

在这里插入图片描述

总结

Lambda 表达式不仅让 C++ 更现代化、更接近函数式编程思想,还大大提高了代码的可读性与开发效率
📝 如果你觉得这篇文章有帮助,欢迎点赞👍、收藏⭐和评论💬。
你的支持是我持续更新优质内容的最大动力!

http://www.xdnf.cn/news/11898.html

相关文章:

  • 计算机视觉处理----OpenCV(从摄像头采集视频、视频处理与视频录制)
  • OpenCV CUDA模块图像处理------创建一个模板匹配(Template Matching)对象函数createTemplateMatching()
  • 自动化生产线,IT部署一站式解决方案-Infortrend KS私有云安全,一机多用
  • [蓝桥杯]模型染色
  • 软珊瑚成分 CI-A:靶向口腔癌细胞的 “氧化利剑” 与 ERK 密码
  • 如何借助Hyper - V在Windows 10中构建安全软件测试环境
  • 编译一个Mac M系列可以用的yuview
  • 设计模式-迪米特法则
  • 2025年- H69-Lc177--78.子集(回溯,组合)--Java版
  • 2025年想冲网安方向,该考华为安全HCIE还是CISSP?
  • 界面组件DevExpress WPF中文教程:Grid - 如何识别行和卡片?
  • 深度解析Mysql中MVCC的工作机制
  • 每日Prompt:每天上班的状态
  • UE 材质基础第三天
  • Spring AI Tool Calling
  • SecureCRT 设置超时自动断开连接时长
  • Pluto论文阅读笔记
  • 双流芯谷元宇宙战略落子,智慧园区建设迈入数字孪生时代
  • 【统计方法】树模型,ensemble,bagging, boosting
  • GlobalSign、DigiCert、Sectigo三种SSL安全证书有什么区别?
  • JavaWeb:前端工程化-ElementPlus
  • 设计模式杂谈-模板设计模式
  • 题山采玉:Day2
  • [Harmony]颜色初始化
  • 国产化Word处理控件Spire.Doc教程:Java实现HTML 转Word自动化
  • GICv3电源管理
  • 防止网站被iframe嵌套的安全防护指南
  • python3GUI--车牌、车牌颜色识别可视化系统 By:PyQt5(详细介绍)
  • 【算法深练】分组循环:“分”出条理,化繁为简
  • 匀速旋转动画的终极对决:requestAnimationFrame vs CSS Animation