lambda表达式
一般性解释
lambda表达式就是一段可调用代码,由于lambda表达式是匿名的,可以保证了不会被不安全访问。
举个栗子
int fun(int x, int y) {
auto f = [](int x, int y) { return x + y; };
std::cout << f(x, y) << std::endl;
}
lambda表达式的格式
[capture] (params) mutable exception -> return type { func body }
capture: 捕获的外部变量
params:形参
mutable指示符:用来说明是否可以修改外部变量
exception:异常相关
return type:返回类型
func body:函数体
其中部分可省略
栗子:
auto f = [](int x, int y) { return x+y; }; //省略return type
auto f = [] { return true; }; //当没有形参的时候省略括号
//实际一点的栗子
vector<int> v {1, 3, 7 ,4 ,6 ,5};
sort(v.begin(), v.end(), [](int a, int b) { return a<b; });
捕获外部变量
意思即在lambda内,使用外部的一些变量。
lamabda表达式可以使用它可见范围内的外部的变量,但是必须明确声明。
栗
int fun() {
int x = 1;
auto f = [x] { std::cout << x << std::endl; };
f(); //在终端上打印变量x ,即1
}
捕获的外部变量类似于参数传递(值传递,引用传递。。)外部变量的捕获也分为值捕获、引用捕获
值捕获栗子
int a = 1;
auto f = [a] { std::cout << a << std::endl; };
a = 2;
f(); //输出1
注意上面输出,如果是值捕获则不能改变外部变量的值,无法编译通过。外部变量改变不会影响lambda里面
引用捕获栗子
int a = 1;
auto f = [&a] { std::cout << a << std::endl; };
a = 2;
f(); //输出2
隐式捕获
也可以让编译器自动推导我们想要值捕获还是引用捕获。
int a = 3;
int b = 2;
auto f = [=] { std::cout << a << std::endl; }; //[]里面写“=”符号,代表值捕获
auto f = [&] { std::cout << b << std::endl; }; //[]里面写“&”符号,代表引用捕获
混合方式(为什么要用混合头痛==
捕获 | 说明 |
---|---|
[] | 不做捕获 |
[变量名] | 值捕获 |
this | 以值的形式捕获this指针 |
[=] | 值捕获 |
[&] | 引用捕获 |
&, x | x用值捕获,其他用引用捕获 |
[=, &a] | a用引用捕获,其他用值捕获 |
值传递在lambda内修改捕获变量的值
使用mutable关键字
int a = 2;
auto f = [a] mutable { a = 2333; std::cout << a << std::endl; };
std::cout << "first" << a << std::endl; //输出2
f(); //输出2333
std::cout << "second" << a << std::endl; //输出2