介绍
一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。和函数类型,lambda有一个返回值,一个参数列表和一个函数体,但比函数多一个捕获列表。具体形式如下:
[捕获列表](参数列表) ->返回值类型 {函数体}
其中:
捕获列表:可以捕获定义lambda表达式所在的函数中定义的局部变量,通常为空即[ ]
参数列表:和普通函数类似。
返回值类型:使用尾置返回,可以省略,一般省略。
函数体:和普通函数类似。
例如比较两个数大小的lambda表达式:
[](int x , int y){ return x > y; } //比较x和y的大小
在上面的表达式中,x,y是接收的参数,如果省略返回值类型,lambda根据函数体推导返回值类型为bool。
lambda的调用方式和普通函数调用方式相同。
int main()
{
auto f = [](int x, int y) {return x > y ? x : y; };//求较大值的lambda
cout << f(10, 20); //像普通函数一样调用lambda
return 0;
}
不带参数lambda
int main()
{
auto f2 = []() {cout << "没有参数" << endl; };
f2(); //调用f2
auto f3 = [] {cout << "没有参数,参数列表的()都可以省略" << endl; };
f3();//调用f3
return 0;
}
如果lambda不带参数,其参数列表的()都可以省略不写(这和普通函数不同)。
使用捕获列表
lambda是定义在函数内部的,它可以通过捕获列表使用函数内部的变量。
int main()
{
const int a = 10;
//求参数x,y和函数局部变量a三者的最大值
auto f = [a](int x, int y) {int z = (x > y ? x : y); return z > a ? z : a; };
int b, c;
cin >> b >> c;
cout << f(b, c) << endl;
return 0;
}
上面的捕获列表设计看似没有必要,因为可以增加一个参数。但在很多情况下参数的个数是固定的。比如算法需要的谓词。如果想传递更多的参数就必须使用捕获列表了。
例如,使用cout_if算法。
#include<algorithm>
#include <iostream>
#include <vector>
using namespace std;
//输出容器的所有元素
template<typename T>
void Show(const T& v)
{
for (const auto x : v)
cout << x << " ";
cout << endl;
}
int main()
{
vector<string> v{"China", "Singapore", "Japan", "India", "Malaysia", "Finland", "France"};
cout << "v:"; Show(v);
//统计国家名称长度小于6的国家数量
cout << "国名长度小于6的国家数量:";
cout << count_if(v.begin(), v.end(), [](const string& s) {return s.length() < 6; }) << endl;
return 0;
}
如果想把上面的程序设计的更灵活,用于统计(国名)长度小于任意参数的国家数量,那么需要在lambda中增加一个长度的参数。但是cout_if的第三个参数只能是一元谓词(只能是一个参数)。那么就会出现语法错误。
//下面这句代码出现语法错误,因为count_if的第三个参数只能是一元谓词,不能有两个参数
count_if(v.begin(), v.end(), [](const string& s,int sz) {return s.length() < sz; });
这时可以通过捕获列表(也可以通过仿函数)解决这个问题。
#include<algorithm>
#include <iostream>
#include <vector>
using namespace std;
//输出容器的所有元素
template<typename T>
void Show(const T& v)
{
for (const auto x : v)
cout << x << " ";
cout << endl;
}
int main()
{
vector<string> v{"China", "Singapore", "Japan", "India", "Malaysia", "Finland", "France"};
Show(v); //输出元素
int sz; //国家名称长度的上限
cout << "请输入需要统计的长度:";
cin >> sz;
//统计国家名称长度小于sz的国家数量
cout << "国名长度小于" << sz << "的国家数量:";
cout << count_if(v.begin(), v.end(), [sz](const string& s) {return s.length() < sz; }) << endl;
return 0;
}
本篇完!