一、为什么要有lambda函数?
举个例子:
在words容器中找到满足谓词的元素。
find_if(words.begin(), words.end(), 谓词);
这个谓词可以看作一个布尔函数,find_if对于每个元素,都会传给谓词判定,如果满足,就返回这个元素的迭代器。
find_if只能接受一元谓词,也就是说,谓词的参数只能有一个,就是find_if传给它的容器里的元素值。
如果想找容器里长度大于6的string怎么办?
//谓词
bool length6(string s)
{
return s.length > 6;
}
find_if(words.begin(), words.end(), length6);
那个6可以自由更换吗?不行,因为find_if只能接受一个参数,那个size(也就是6)不能传进去。
于是,lambda出现了。用它做谓词,接受的参数不受限制。
二、lamba函数
1. 格式:
auto 函数名 = [捕获列表] (参数列表) -> return type {函数体};
这里参数列表和返回值可以省略,捕获列表和函数体不能省。
auto f = []{return 3;};
调用形式:f()
2. 捕获列表
捕获列表里的参数,是当前函数里的变量。
int a = 3;
auto f = [a]{return a;};
cout << f();//输出的是3
捕获的值分为两种情况:
(1)拷贝捕获。在函数定义之后,捕获的值也就确定了,之后不能更改。
(2)引用捕获。函数定义之后,捕获的值与当前的值相同。
举例:
size_t v1 = 42;
auto f = [v1]{return v1;};
v1 = 0;
cout << f();//输出的是42
size_t v1 = 42;
auto f = [&v1]{return v1;};
v1 = 0;
cout << f();//输出的是0
- 返回类型
一般不用指定,会根据return的值自动判断。
需要注意的是,当函数体只有return语句时,会自动判断,而除了return还有其他语句时,默认为void。
三、什么时候使用lambda
- 算法函数只接受一元谓词时。
开头那个find_if可以用lambda改为:
auto wc = find_if(words.begin(),words.end(),
[sz](const string &a)
{return a.size() >= sz};
- 函数体很短时。
lambda可以在使用的时候临时写,如果只有三两句,用lambda很方便,每次使用时写一下就行。如果多的话,还是用函数比较方便。