4、匿名函数lambda的使用
一、格式
[捕获列表](参数列表)mutable(可选) 异常属性->返回类型{
//函数体
}
- 捕获列表是可以自动捕获参数的。
- 一般编译器可以自己推断出返回类型,所以可以不用写。 如下:
[捕获列表](参数列表){函数体}
二、捕获列表
1、按值和引用传递
- 捕获列表是可以自动捕获参数的。
void test(){
int c =12;
int d =30;
int e = 10;
auto add =[c,d,&e](int a,int b)->int{
cout<<"d="<<d<<endl;
cout<<"e="<<e<<endl;
return c;
};
d=20;
e=20;
cout<<add(1,2)<<endl;
}
int main(){
test();
//d=30
//e=20
//12
}
2、隐式捕获
- 手动写捕获列表有时候是非常复杂的,这种机械的工作可以交给编译器来处理,这时候可以在捕获列表中写一个**&或=向编译器声明采用引用捕获或者值捕获**。
- [=]就可以使用外面的变量了,但是是const类型。 [&]也可以使用外面的变量。
void test(){
int c =12;
int d =30;
auto add =[&](int a,int b)->int{
c=a;
cout<<"d="<<d<<endl;
return c;
};
d=20;
cout<<add(1,2)<<endl;
cout<<"c="<<c<<endl;
}
int main(){
test();
//d=20
//1
//c=1
}
3、空捕获列表
捕获列表[]中为空,表示lambda不能使用所在函数中的变量。
void test(){
int c =12;
int d =30;
auto add =[](int a,int b)->int{
c=a;//编译错误
cout<<"d="<<d<<endl;//编译错误
return c;//编译错误
};
d=20;
cout<<add(1,2)<<endl;
cout<<"c="<<c<<endl;
}
4、表达式捕获
以上3种捕获都是左值捕获,如果要右值捕获使用的是 c++14 。
void test{
auto important = make_unique<int>(1);
auto add=[v1=1,v2=std::move(important)](int x,int y)->int{
return x+y+v1+(*v2);
};
}
5、泛型lambda
在C++14之前,lambda表示的形参只能指定具体的类型,没法泛型化。C++14后,lambda函数的形式参数可以使用auto关键字来产生意义上的泛型:
void test(){
auto add = [](auto x,auto y){
return x+y;
};
}
6、可变lambda
- 采用值捕获的方式,lambda不能修改其值,如果要修改,使用mutable修饰。
- 采用引用捕获的方式,lambda可以直接修改其值。