什么是C++中的Lambda表达式?它的作用是什么?Lambda表达式可以捕获哪些类型的变量?有哪些捕获方式?

什么是C++中的Lambda表达式?它的作用是什么?

C++中的 Lambda 表达式:

Lambda 表达式是 C++11 引入的一种匿名函数,可以在需要的地方直接定义并使用。

通常的形式是

复制代码
` `[捕获列表](参数列表)` `-> 返回类型 { 函数体 };

作用:

  • 简化代码 :可以使代码更加简洁紧凑,避免定义单独的函数。例如在对容器进行排序、遍历等操作时,可以直接传入 Lambda 表达式作为参数,无需提前定义函数。
  • 增加灵活性 :可以方便地捕获外部变量,根据不同的上下文进行灵活的操作。捕获列表可以指定以值捕获或引用捕获的方式获取外部变量。
  • 提高代码可读性 :尤其是在一些短小的、特定的操作中,使用 Lambda 表达式可以让代码的意图更加清晰,直接在使用的地方看到具体的操作逻辑。

Lambda表达式可以捕获哪些类型的变量?有哪些捕获方式?

Lambda 表达式可捕获的变量类型:

  • 局部变量:在 Lambda 表达式所在作用域内定义的普通变量。
  • 静态变量:在程序运行期间一直存在的静态变量。
  • 全局变量:整个程序都可访问的全局变量。
  • 函数参数:传递给包含 Lambda 表达式的函数的参数。

lambda有以下优点:

  • 可以就地匿名定义目标函数与函数对象,不需要额外写一个函数
  • lambda是一个匿名的内联函数

lambda表达式定义了一个匿名函数,语法如下:

复制代码
capture](params)-> ret {body;};

其中capture是捕获列表,params是参数列表,ret是返回值类型,body是函数体。

捕获列表[]:捕获一定范围的变量

参数列表[]:和普通函数的参数列表一样,如果没有参数参数列表可以省略不写

复制代码
auto fun =` `[](){return` `0;};`
`auto fun =` `[]{return` `0;};
捕获列表
  • []不能捕获任何变量
  • [&]捕获外部作用域中的所有变量,并且按照引用捕获
  • [=]捕获外部作用域中的所有变量,按照之捕获,拷贝过来的副本在函数体内是只读的
  • [=,&a]按值捕获外部作用域得所有变量,并且按照引用捕获外部变量a
  • [bar]按值捕获bar变量,不捕获其他变量
  • [this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限

捕获方式:

  • 值捕获 :以值的方式捕获外部变量,在 Lambda 表达式内部是这些变量的副本。例如 [a,b]() ,这里 a 和 b 都是以值捕获的方式被捕获到 Lambda 表达式中。
  • 引用捕获 :以引用的方式捕获外部变量,在 Lambda 表达式内部可以直接修改外部变量的值。例如 [&a,&b]() ,这里 a 和 b 都是以引用捕获的方式被捕获到 Lambda 表达式中。
  • 混合捕获 :可以同时使用值捕获和引用捕获,例如 [=,&a]() ,这里除了变量 a 以引用捕获外,其他外部变量都以值捕获的方式被捕获。
  • 隐式捕获 :使用 [=] 表示以值捕获所有外部变量,使用 [&] 表示以引用捕获所有外部变量。
复制代码
int` `main()`
`{`
    `int a=10,b=20;`
    `auto fl=[]{return a;};` `// 错误,没有捕获外部变量,因此无法访问变量 a`
    `auto f2=[&]{return a++;};//正确,使用引用的方式捕获外部变量,可读写`
    `auto f3=[=]{return a;};` `//正确,使用值拷贝的方式捕获外部变量,可读`
    `auto f4=[=]{return a++;};//错误,使用值拷贝的方式捕获外部变量,可读不能写     `
    `auto f5=[a]{return a+b;};// 错误,使用拷贝的方式捕获了外部变量 a,没有捕获外部变量 b,因此无法访问变量 b`
    `auto f6=[a,&b]{return a+(b++);};` `// 正确,使用拷贝的方式捕获了外部变量 a,只读,使用引用的方式捕获外部变量 b,可读写`
    `auto f7 =[=,&b]{return a+(b++);};` `//正确,使用值拷贝的方式捕        获所有外部变量以及 b 的引用,b 可读写,其他只读`
    `return` `0;`
`}
复制代码
class` `Test`
`{`
`public:`
    `void` `output(int x,int y)`
    `{`
        `auto xl=]{return m number;};// 错误,没有捕获外部变量,不能使用类成员 m number`
        `auto x2=[=]{returnmnumber+x+y;};//正确,以值拷贝的方式捕获所有外部变量`
        `auto x3=[&]{returnmnumber+x+y;};//正确,以引用的方式捕获所有外部变量`
        `auto x4=thisl{returnmnumber;};//正确,捕获 this指针,可访问对象内部成员`
        `auto x5=[this]{returnm number+x+y;};//错误,捕获 this指针,可访问类内部成员,没有捕获到变量x,y,因此不能访问。`
        `auto x6=[this,x,y]{returnmnumber+x+y;};// 正确,捕获 this 指针,x,y`
        `auto x7=[this]{return m number++;};//正确,this 指针,并且可以修改对象内部变量的值捕获`
        `}`
    `int mnumber=100;`
`};
返回值

一般情况下,不指定 lambda 表达式的返回值,编译器会根据 return 语句自动推导返回值类型,但是需要注意的是 lambda 表达式不能通过列表初始化自动推导出返回值类型。

复制代码
//可以自动推导出返回值类型`
`auto f=[](int i)`
`{`
    `return i;`
`}`
`//不能推导出返回值类型`
`auto fl=[]()`
`{`
    `return{1,2};//基于列表初始化推导返回值,错误`
`}`
`//正确显示声明了函数的返回值类型`
    `auto fl=[]()-> vector<int>`
    `{`
        `return` `{1,2};//基于列表初始化推导返回值,错误`
    `};
相关推荐
cs82198483111 分钟前
QT 设置高DIP支持多分屏幕,window缩放比例问题等
开发语言·qt·依赖倒置原则
gxchai19 分钟前
用PythonSudio在控件中添加、删除控件,并传递参数(以ScrollBox中添加删除按钮为例)
开发语言·python
码上有前20 分钟前
Java高级教程:数据结构、集合框架、ArrayList与LinkedList深度解析
java·数据结构·python
榕树子32 分钟前
[java] 什么是 Apache Felix
java·开发语言·apache
一只鸡某32 分钟前
实习冲刺第三十一天
数据结构·c++·算法·leetcode·排序算法
极客先躯33 分钟前
高级java每日一道面试题-2024年11月23日-JVM篇-什么时候会出发FullGC?
java·jvm·fullgc·jvm篇·老年代内存不足·system.gc·减少full gc的策略
牙牙要健康36 分钟前
【深度学习】【RKNN】【C++】模型转化、环境搭建以及模型部署的详细教程
c++·人工智能·深度学习
雯0609~39 分钟前
C#winform:连接mysql,并将数据展示到页面
开发语言·c#
@Crazy Snail40 分钟前
C# 多线程异步--Token
开发语言·c#·token·task
AICodeThunder42 分钟前
C++知识点总结(58):序列型动态规划
开发语言·c++·动态规划