C++ lambda表达式
C++ lambda表达式
C++11引入了lambda表达式,主要用来解决调用函数时需要传入一个可调用对象的情况。因为很多情况下,传入的函数只用一次,如果特地去声明一个函数,但是后面没有再次调用,此时的函数就失去了重用性。同时,有的函数接收的可调用对象只能接受含有一个参数的可调用对象,此时用lambda表达式可以很好的处理这种情况
语法
[捕获列表](参数列表)->返回类型{函数体}
参数列表
参数列表与普通函数的参数列表一样,同样是参数类型和参数名。
但与普通函数不同的是,lambda不允许有默认参数。这一点比较好理解,因为lambda通常作为一次性使用,因此默认参数基本上是没有意义的
返回类型
返回类型必须使用后置返回类型,如果函数体只有一句return语句的话,可以省略返回类型,编译器会根据return语句推断返回类型,否则默认返回void
函数体
函数体育普通函数的函数体一样,由于lambda表达式主要是一次性的,且经常嵌入到函数调用的参数中,因此一般来说函数体是很简单的,通常只有一条return语句,这也是为什么返回类型只有一条return语句时可以不写返回类型的原因。
如果函数体有较复杂的逻辑处理,需要较多的语句,建议声明一个函数。
捕获列表
lambda与普通函数最大的区别就是由中括号括起来的捕获列表
捕获列表中不需要声明参数的类型,而是使用局部变量的名字,它只能使用那些明确指明的名字。
捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和其所在函数之外的名字
捕获
值捕获
值捕获类似于值传递,值捕获的前提是变量可以拷贝
被捕获的变量的值是在lambda创建时拷贝的,而不是调用时拷贝
lambda的创建是建立一个临时类的对象,如果是使用值捕获的方式捕获参数,相当于类内部有一个变量保存捕获的值,在创建对象的时候用捕获到的值初始化类内部的变量。
因此,lambda创建后,对被捕获的变量进行修改不会影响到lambda内对应的值
引用捕获
类似于参数传递,有值捕获,也有引用捕获
引用是将名字绑定到对象上,所以在lambda创建后,修改使用引用捕获的变量的值,会改变lambda内部变量的值。
当我们希望lambda表达式捕获一个ostream时,由于ostream不能拷贝,必须使用引用捕获,所以引用捕获是有必要的。
引用捕获也带来了一个问题,就是程序员必须保证在lambda执行时,变量时存在的。
隐式捕获
在捕获列表中写一个&或=,可以指示编译器推断捕获列表
“&”告诉编译器采用引用捕获的方式
“=”告诉编译器采用值捕获的方式
当混合使用隐式捕获和显式捕获时,捕获列表中的第一个元素必须是一个”&”或一个”=”
如果采用引用捕获或者捕获一个指针或迭代器,则需要确保lambda执行时这些对象仍然有效,因此应尽量减少捕获的数据量来避免潜在的捕获导致的问题。可以的话,尽量避免捕获指针和引用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通