C++ lambda表达式
1.Lambda表达式(匿名函数)
lambda表达式用来表示一种匿名函数。所谓匿名函数,简单地理解就是没有名称的函数。lambda表达式一般可以解决仿函数问题。例如:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int vala, int valb)
{
return vala < valb;
}
int main()
{
vector<int> myvec{ 3, 2, 5, 7, 3, 2 };
vector<int> lbvec(myvec);
sort(myvec.begin(), myvec.end(), cmp); // 旧式做法
cout << "predicate function:" << endl;
for (int it : myvec){
cout << it << ' ';
}
cout << endl;
// Lambda表达式
sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; }); cout << "lambda expression:" << endl;
for (int it : lbvec){
cout << it << ' ';
}
}
2.lambda表达式语法
先来看一下lambda表达式的语法形式:
[ capture ] ( params ) opt -> ret { body; };
其中carpture是捕获列表,params是参数,opt是选项,ret则是返回值的类型,body则是函数的具体实现。
1. 捕获列表描述了lambda表达式可以访问上下文中的哪些变量。
[]:表示不捕获任何变量
[=]:表示按值捕获变量
[&]:表示按引用捕获变量
[this]:值传递捕获当前的this
例如:
[var] 表示值传递方式捕捉变量var;
[=] 表示值传递方式捕捉所有父作用域的变量(包括this);
[&var] 表示引用传递捕捉变量var;
[&] 表示引用传递方式捕捉所有父作用域的变量(包括this);
[this] 表示值传递方式捕捉当前的this指针;
[=,&vala,&valb] 表示以引用传递的方式捕捉变量vala和valb,以值传递方式捕捉其它所有变量;
[&,vala,this] 表示以值传递的方式捕捉变量vala和this,引用传递方式捕捉其它所有变量。
[=,valx] // error, 捕获列表不允许变量的重复传递
[&,&this] // error 这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复
2. params表示lambda的参数,用在{}中。
3. opt表示lambda的选项,例如mutable,exception。
4. ret表示lambda的返回值,也可以显示指明返回值,lambda会自动推断返回值,但是值得注意的是只有当lambda的表达式仅有一条return语句时,自动推断才是有效的。
[](double valx )->double{int valy = valx ;return valx - valy;};
虽然lambda表达式是匿名函数,但是实际上也可以给lambda表达式指定一个名称,如下表示:
auto func = [](int valx ){return valx % 3 ==0;};
此后再需要使用该lambda表达式,就可以使用f()来代替。举一个例子:
#include <iostream>
using namespace std;
int main()
{
int vala = 5, valb = 6;
auto func = [=]{return vala + valb;};//[=]按值捕获了vala和valb
cout << func() << endl;
return 0;
}
3.按值捕获和按引用捕获
按值捕获和按引用捕获的用法通过下面这个例子来看一下。
#include <iostream>
using namespace std;
int main()
{
int vala = 5;
auto func1 = [=]{return vala + 10;};//按值捕获vala
auto func2 = [&]{return vala + 10;};//按引用捕获a
cout << func1() << endl;
cout << func2()<< endl;
vala++;
cout << func1() << endl;
cout << func2() << endl;
return 0;
}
如果希望lambda函数在调用时访问的外部变量是最新的,我们就需要使用按引用捕获。
#include <iostream>
using namespace std;
int main()
{
int vala = 5;
auto func = [=]{return vala *= 5;};//按值捕获a
cout << func() << endl;
return 0;
}
默认情况下,lambda函数是一个const函数,而mutable也可以取消常量性。例如 :
#include <iostream>
using namespace std;
int main()
{
int vala = 5;
auto func = [=]()mutable{return vala *= 5;};//取消常量性
cout << func() << endl;
return 0;
}