介绍
一个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; };//求较大值的lambdacout << f(10, 20); //像普通函数一样调用lambdareturn 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;
}
本篇完!