简单的介绍一下lambda表达式在不同地方使用的作用,在STL算法函数,在类里面的使用,以及相关应用举例
定义lambda的时候,编译器生成一个与lambda对应的新的未命名的类类型
参考Primer C++(第五版) 10.3.2 lambda 表达式 p346
到目前为止,我们使用过的仅有的两种可调用对象是函数和函数指针。
还有其他两种可调用对象:重载了函数调用运算符的类,以及lambda表达式(lambda expression)。
[capture list](parameter list)->return type {function body}
//[捕获列表](参数列表)->返回值 {函数主题}
//一个典型的例子
auto cmp = [](const int & lhs, const int & rhs){return lhs<rhs};
int cap1;
auto cmp = [cap1]{return cap1};
好处
举个例子,以sort函数为例子
//对nums进行降序排序
vector<int> nums = {1,2,3,1,3,5,2,1}
//方式1
auto cmp = [](const int & lhs, const int & rhs){return lhs>rhs};
sort(nums.begin(),nums.end(),cmp);
//方式2
sort(nums.begin(),nums.end(),[](const int & lhs, const int & rhs){return lhs<rhs});
举个例子,以priority_queue为例子
//创建一个大根堆
vector<int> nums = {1,2,3,1,3,5,2,1}
//1. 定义lambda表达式
auto cmp = [](const int & lhs, const int & rhs){return lhs>rhs};
//2. 定义priority_queue,
priority_queue<int,vector<int>, decltype(cmp)> pqueue;
sort(nums.begin(),nums.end(),[](const int & lhs, const int & rhs){return lhs<rhs});
//3. 填充元素
for(auto num:nums)
pqueue.push(num);
参考Primer C++(第五版) 10.3.2lambda表达式 p345
虽然一个 lambda可以出现在一个函数中,使用其局部变量,但它只能使用那些明确指明的变量。一个lambda通过将局部变量包含在其捕获列表中来指出将会使用这些变量。捕获列表指引 lambda在其内部包含访问局部变量所需的信息。
参考Primer C++(第五版) 10.3.2lambda表达式 p348
一个lambda只能使用他捕获列表中存在的他所在函数中的局部变量。
这里举一个最简单的例子,用于比较一个输入的形参是否比judge值大。
void myfun()
{
int judge = 100;
auto judge_fun = [judge](int aim){return judge < aim};
// auto judge_fun = [](int aim){return judge < aim};这一行不捕获直接使用judge就会报错
cout<<judge_fun();
}
参考Primer C++(第五版) 10.3.3lambda捕获和返回 p352
类似于参数传递,变量的捕获的方式可以是值或者引用
值捕获的前提是变量可以拷贝,而且是在lambda创建的时候拷贝,而非调用时
void fcn1()
{
int v1 = 42;
auto f = [v1]{ return v1 };
v1 = 0;
auto j = f(); //j = 42而不是0,lambda创建后修改v1不会改变捕获的值
}
需要保证运行的时候引用捕获的值依然存在
void fcn1()
{
int v1 = 42;
auto f = [&v1]{ return v1 };
v1 = 0;
auto j = f(); //j = 42而不是0,lambda创建后修改v1不会改变捕获的值
}
非显式,让编译器推断捕获列表,可以看上面的表格的写法。
void fcn1()
{
int v1 = 42;
auto f = [v1]{ return ++v1 };
v1 = 0;。
auto j = f(); //j = 43
}
引用捕获的话同一般的函数。
有时候编译器无法推断返回类型,比如有多个等价的if语句里面的return。
auto fcn = [](int i){if (i < 0) return -i; else return i;};//会报错
auto fcn = [](int i)->int{if (i < 0) return -i; else return i;};//不会报错
Primer C++(第五版) 10.3.2lambda表达式 p345
Primer C++(第五版) 10.3.2 lambda 表达式 p346
Primer C++(第五版) 10.3.2lambda表达式 p348
Primer C++(第五版) 10.3.3lambda捕获和返回 p352