解决什么问题
对于c++中的lambda表达式,在其它的高级语言中可能没有这个概念,而是用的匿名函数,其实本质上是一个东西。
常用于编写函数,而只调用一次的情况;例如一个按钮点击触发一个函数,只有这一个地方调用;不写又不行,写又很浪费;故引入了匿名函数。
用法格式
1 基本用法
[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}
例如:
int c = [] (int a, int b) -> int {
return a+b;
}(1,2);
匿名函数没有名字所以在定义的时候就立马调用
上面代码等价于
int Foo(int a, int b){
return a+b;
}
int c = Foo(1, 2);
2 改造与auto自动推到结合
将函数体存储起来,用自动推到auto。
//定义
auto f = [](int a, int b){
return a+b;
};
//调用
int c = f(1,2);
3 函数式编程
对于表达式lambda作者认为所有的函数都可以用lambda来表示,用一个lambda表达式,他自己在数学上已经证明了,但是这样代码可读性不高。
int c = [] (int n){
return [n](int x){
return n + x;
}(1);
}(2);
说明了lambda可以内部嵌套;程序如果按照这种方式组织就是函数式编程
函数式编程结果至于参数有关,不会被全局变量等影响;特别适合在多线程并发编程中只依赖内部。典型代表就是go语言
auto f = [](int n){
return [n](int x){
return n + x;
};
};
f(1)(2);
4 捕获列表
捕获参数列表可以按照值捕获,引用捕获,或者两者结合。
值捕获在函数内修改后,函数外的不会变化,当有多个匿名函数的时候,每个匿名函数都维护一个自己的值。
例如:
int t = 10;
auto f = [t](){
std::cout << t << std::endl;
return ++t;
std::cout << t << std::endl;
};
std::cout << f() << std::endl; // 打印10,11
std::cout << t << std::endl; //打印10
t修改无法修改到外面的。但是如果加上mutable描述符后每个匿名函数只能修改自己的,但是全局的还是不会变动。
int t = 10;
auto f1 = [t]() mutable{
std::cout << "f1:t" << t << std::endl;
++t;
std::cout << "f1:t" << t << std::endl;
return t;
};
auto f2 = [t]() mutable{
std::cout << "f2:t" << t << std::endl;
++t;
std::cout << "f2:t" << t << std::endl;
return t;
};
std::cout << f1() << std::endl; // 10 11
std::cout << f2() << std::endl; // 10 11
std::cout << f1() << std::endl; // 11 12
std::cout << f2() << std::endl; // 11 12
std::cout << t <<std::endl; // 10
捕获的方式:按值捕获,按引用捕获
实际项目中使用
std::vector<int> v = {1,2,3,4,5};
for(int i = 1; i < v.size(); i++){
//业务处理
}
等价与
for_each(v.begin(), v.end(), [](int n){
//业务处理
});