C++11 lambda表达式
1 什么是lambda表达式
是一个闭包;是一个能够在作用域中捕获变量的匿名函数对象。
2 什么是lambda组成部分
1、捕获:可以为0或者多个分割列表
2、参数列表:可有可无
3、mutable: 可变规范可有可无
4、throw(): 异常规范 可有可无
5、返回类型:可有可无
6、lambda本地
2.1 []捕获
2.1.1 捕获形式:
- [] : 不捕获任何外部变量
- [=] : 以值的形式捕获所有外部变量
- [var1, var2, … ] : 以值的形式捕获多个外部变量(变量用逗号分)
- [&var1, &var2,…] : 以引用的形式捕获多个外部变量(变量用逗号分割)
- [&] : 以引用的形式捕获所有外部变量
- [=,&var1] :以引用形式捕获var1,其余外部变量以值的形式捕获
- [&,var1] :以值形式捕获var1,其余外部变量以引用的形式捕获
- [this] : 以值的形式捕获this指针
2.1.2 []不捕获任何外部变量:
#include <algorithm>
#include <iostream>
using namespace std;
// 测试不捕获任何变量
void fun1(){
int var1 = 1;
int var2 = 2;
[]() noexcept {
int i = var1;
int j = var2;
cout << i << " " << j << endl;
};
}
int main(){
fun1();
return 0;
}
编译报错:
lambda不捕获变量,内部就不能使用。
2.1.2 修改非mutable值捕获:
#include <algorithm>
#include <iostream>
using namespace std;
//测试修改值捕获
void fun2(){
int var1 = 1;
int var2 = 2;
[var1, var2]() noexcept {
int i = var1;
int j = ++var2;
cout << i << " " << j << endl;
};
}
int main(){
fun2();
return 0;
}
编译报错:
var2是值捕获不能被修改
2.1.3 重复捕获:
#include <algorithm>
#include <iostream>
using namespace std;
//重复捕获
void fun3(){
int var1 = 1;
int var2 = 2;
[=, var2]() noexcept {
int i = var1;
int j = var2;
cout << i << " " << j << endl;
}();
}
int main(){
fun3();
return 0;
}
编译告警:
显示的var值拷贝和默认的全值拷贝冗余
2.1.4 混合捕获:
#include <algorithm>
#include <iostream>
using namespace std;
void fun4(){
int var1 = 1;
int var2 = 2;
int var3 = 3;
//值捕获
[=]() noexcept {
int i = var1;
int j = var2;
cout << "i=" << i << " " << "j=" << j << endl;
}();
//引用捕获,修改外部变量值i,j的值
[&]() noexcept {
int i = ++var1;
int j = ++var2;
cout << "i=" << i << " " << "j=" << j << endl;
}();
//var1引用捕获,var2,var3值捕获
[=, &var1]() noexcept {
int i = ++var1;
int j = var2;
int k = var3;
cout << "i=" << i << " " << "j=" << j <<
" " << "k=" << k << endl;
}();
}
int main(){
fun4();
return 0;
}
输出结果:
2.2 参数列表
Lambda表达式中传递参数和有名函数参数列表一样
2.3 mutable
#include <algorithm>
#include <iostream>
using namespace std;
void fun6(){
int var1 = 1;
int var2 = 2;
[=]() mutable noexcept {
int i = ++var1;
int j = ++var2;
cout << i << " " << j << endl;
}();
}
int main(){
fun6();
return 0;
}
输出结果:
2.4 noexcep/throw()
noexcept == throw() == noexcept(true)
noexcept目的是会防止异常扩散。如果出现异常,会调用terminate()->abort()结束程序。
#include <algorithm>
#include <iostream>
using namespace std;
void fun7(){
int var1 = 1;
int var2 = 2;
[=]() mutable noexcept {
int i = ++var1;
int j = ++var2;
cout << i << " " << j << endl;
throw(5);
}();
}
int main(){
fun7();
return 0;
}
运行结果崩溃
3 lambda优点
1、简洁
2、距离执行代码近,便于阅读理解代码。
3、可以捕获作用域中的任何变量
4 lambda可以直接使用无需捕获的变量类型
全局变量,thread_local 变量,static变量都是可以直接使用,无需捕获。
#include <algorithm>
#include <iostream>
using namespace std;
int g_a = 90;
thread_local unsigned int rage = 77;
void fun8(){
static int var1 = 1;
const int d1 = 5;
[]() mutable noexcept {
int j = ++var1;
++g_a;
++rage;
cout << "g_a:" << g_a << " "<< " j:" << j << " "<< " rage:" << rage << endl;
cout << "d1:" << d1 << endl;
}();
}
int main(){
fun8();
return 0;
}
输出结果: