什么是lambda表达式?
一个lambda
表达式表示以一个可以调用的代码单元。或者理解为一个匿名的内联函数。与任何函数类似,一个lambda
具有返回类型、一个参数列表和一个函数体。与函数不同,lambda
可能定义在函数内部。
为什么要有lambda表达式?
我们知道,在STL
所提供的算法中,往往有两个版本。其中一个版本表现最直观的的某种运算,第二个版本则表现出最泛化的演算流程,允许用户“以template
参数来指定所要采取的策略”。以sort()
为例,第一版本是默认从小到大排序(operator<),第二个版本则是允许你指定某种“操作”,使得排序后的两个相邻元素都能令该操作结果为true
。事实上,第二版本允许我们想算法传递任何类别的可调用对象。这个“可调用对象”为第二个版本的第三个参数,被称为“谓词”。
可调用对象
C++的可调用对象有5类:
1. 函数
2. 函数指针
3. 重载了函数调用运算符的类
4. bind创建的对象
5. lambda表达式
而在标准算法中将“谓词”分为两类:一元谓词(只接受一个参数)、二元谓词(接受两个参数)。
但是我们在使用一个算法中,要使用更多的参数,超出了谓词的限制,或者调用的函数有时候只用一次,重用性太差,那我们就要解决这些问题。
C++11
就引入了lambda表达式
来解决这些问题。
lambda表达式怎么用?
1. 语法
1. [captures](params) -> return type { function body }
2. [captures](params) { function body }
3. [captures] { function body }
captures
为捕获列表,为lambda中定义的局部变量的列表。
params
表示参数列表。
return type
表示返回类型,为尾随返回类型。
function body
为函数体。
上面三种用法中,我们可以看出来,参数列表和返回类型可以忽略,但是必须包含捕获列表和函数体。
lambda 捕获
[]:lambda不能使用所在函数的变量。
[=]:值捕获,lambda表达式可以以拷贝的方式访问函数中的变量的值。
[&]:引用捕获,lambda表达式中以引用的方式访问函数中的变量的值。
[=,&]:值捕获和引用捕获混合使用。
[var]:指定捕获或拷贝。
[this]:捕获this指针。
举例
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
int main()
{
std::vector<int> a={1,2,3,4,5};
std::for_each(a.begin(),a.end(),[](int i){ std::cout<<i<<" "});
//C++14 lambda可以拥有自身的默认参数
auto func=[](inr i=6){return i+4;};
std::cout<<func()<<std::endl;
//值捕获和引用捕获
int b=1024,c=2048;
auto func2=[b,&c]{
std::cout<<i<<std::endl;
std::cout<<&j<<std::endl;
};
func2();
//与stl算法结合,找出a中大于3的一个元素
int x=3;
auto d=find_if(a.begin(),a.end(),
[x](int num)
{return num>x;});
return 0;
}