解决什么问题
对于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){ //业务处理 });