/*C++11 Lambda函数 入门 */
#include <iostream>
using namespace std;
int main(){
int var1 = 1, var2 = 2;
// auto 是关键字, add_param 是函数名称, = 后面是函数体,[]是lamda 引出符,
//()表示接受参数,若无参数,可省略()
//->表示后面为函数体,可省略.
// int 为返回值类型,无返回值,可省略
//{} 内为函数体,可以使用参数及父作用域变量
//可以在函数内直接定义lambda函数, 其方便的地方是可以直接访问父作用域变量
auto add_param = [](int x, int y)->int {return x + y; };
cout << add_param(var1, var2)<<endl; //3
// [=]以值传递的方式捕获父作用域变量
auto add_2var = [=] {return var1 + var2; };
cout << add_2var() << endl; //3
// [=]以值传递的方式捕获父作用域变量, 父作用域变量是不能直接修改的
// 因为[=]默认是const 属性
// [&]以引用方式捕获父作用域变量,就可以直接修改父作用域变量
// 捕获父作用域变量,其实跟函数的参数传递是一样的,只是这里是隐含了调用关系.
var1 = 3;
auto fun2 = [&](int x) {var2 = var1 + x; var1 = 1; };
fun2(3);
cout << var1 <<" "<< var2 << endl;//1 6
var1 = 10; var2 = 11; //重新赋值
//Lambda [=] 默认是const属性,直接赋值会出现编译错误. assignment of read-only variable ‘var1’
// 加mutable 修饰符,就可以在函数体里修改var1,var2, 但退出后值不变,还是10,11
// auto fun3 = [=](int x) mutable {var2 = var1 + x; var1 = 1; };
// 以引用方式捕获父作用域变量,可以直接修改
auto fun3 = [&](int x) {var2 = var1 + x; var1 = 1; };
fun3(3);
cout << var1 << " " <<var2<< endl; //1,8
var1 = 1; var2 = 2; //重新赋值
// 以值方式捕获父作用域变量, 加mutable 修饰符,就可以在函数体里修改, 但退出后值不变,还是1 2
auto fun4 = [=](int x, int y) mutable->int {var1 += x; var2 += y; return var1 + var2; };
int t = fun4(10, 20);
cout << t << endl; //33
cout << var1 <<" "<< var2 << endl; //1 2
return 0;
}
/*
小结: lambda 函数存在的意义:
lambda 函数可以直接访问父作用域变量(以值方式传递或以引用方式传递)
[=]以值传递的方式捕获父作用域变量, 父作用域变量是不能直接修改的
加mutable 修饰符,就可以在函数体里修改, 但退出后值不变
[&]以引用方式捕获父作用域变量,就可以直接修改父作用域变量
于是乎, 当你在写一个函数时,如果你愿意,就可以随便再定义一个lambda函数,
它可以操控该函数的变量. 使得书写函数更灵活了!
*/