Lambda表达式简介
- Lambda 表达式是 C++11 中语法之一
- Lambda 表达式把函数看作对象,把这个表达式当做对象使用
- Lambda 表达式可以赋值给变量,也可以当做参数传给真正的函数
Lambda表达式语法解析
[capture-list] (parameters) mutable -> return-type { statement }
- [capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来
判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda
函数使用。 - (parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以
连同()一起省略 - mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。使用该修饰符时,参数列表不可省略(即使参数为空)。 - ->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回
值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
导。 - {statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获
到的变量。
int main()
{
// 最简单的lambda表达式, 该lambda表达式没有任何意义
[] {};
// 省略参数列表和返回值类型,返回值类型由编译器推导为int
int a = 3, b = 4;
[=] {return a + 3; };
// 省略了返回值类型,无返回值类型
auto fun1 = [&](int c) {b = a + c; };
fun1(10);
cout << a << " " << b << endl;
// 各部分都很完善的lambda函数
auto fun2 = [=, &b](int c)->int {return b += a + c; };
cout << fun2(10) << endl;
// 复制捕捉x
int x = 10;
auto add_x = [x](int a) mutable { x *= 2; return a + x; };
cout << add_x(10) << endl;
cout << x << endl;
return 0;
}
通过上述例子可以看出,lambda表达式实际上可以理解为无名函数,该函数无法直接调
用,如果想要直接调用,可借助auto将其赋值给一个变量
捕获列表说明
捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式传值还是传引用。
- [var]:表示值传递方式捕捉变量var
- [=]:表示值传递方式捕获所有父作用域中的变量(包括this)
- [&var]:表示引用传递捕捉变量var
- [&]:表示引用传递捕捉所有父作用域中的变量(包括this)
- [this]:表示值传递方式捕捉当前的this指针
mutable关键字
- 如果使用按值捕获,并且想修改拷贝的值,可以使用mutable关键字修饰
int a = 10;
auto lmd = [a] () mutable {
cout << a << endl; // 10
a += 2; // 合法操作,并且不影响 lambda 表达式外面的变量a的值
cout << a << endl; // 12
};
cout << a << endl; // 10
Lambda表达式使用示例
- 将 Lambda 表达式当做函数对象使用
#include <iostream>
using namespace std;
int main()
{
int a = 10, b = 4;
auto lamb = [&a, &b](int&& x, int&& y) -> void {
cout << a << " " << b << " " << x << " " << y << endl;
};
lamb(1, 2);
return 0;
}
- 将 Lambda 表达式当做函数参数使用:常用于替换仿函数
struct S
{
int x;
int y;
}s[2];
struct CmpFun //仿函数进行排序
{
bool operator()(const S& ls, const S& rs)
{
if (ls.x == rs.x)return ls.y > rs.y;
return ls.x > rs.x;
}
};
int main()
{
s[0].x = 0, s[0].y = 2;
s[1].x = 0, s[1].y = 3;
sort(s, s + sizeof(s) / sizeof(s[0]), [](S& a, S& b) { //左闭右开区间
if (a.x == b.x)
return a.y > b.y;
return a.x > b.x;
});
//sort(s, s + sizeof(s) / sizeof(s[0]), CmpFun());
for (auto e : s)
cout << e.x << " " << e.y << endl;
return 0;
}