Lambda表达式是C++11非常重要也是最常用的特性之一,它的本质是一个函数指针,可以在在函数内部定义一个函数,增加代码的可读性。
语法结构
[捕获列表] (参数列表) -> 返回值 { 函数体 }
捕获列表:
null | 不捕获 | 只能访问函数内部的变量和全局变量。 |
= | 值捕获 | 对Lambda表达式所在函数的作用域内的变量以值的形式捕获,不可修改,只可访问。 |
& | 引用捕获 | 对Lambda表达式所在函数的作用域内的变量引用捕获,可以修改。 |
也可以混合使用,比方说 [=,&b] 的含义是:值捕获其他变量,引用捕获变量B,所以在这个Lambda表达式中,其他变量只可访问,不可修改,但是变量B可以修改。
捕获列表不可省略。
参数列表:
与普通函数的参数列表相同,特殊的是,如果该函数没有参数,参数列表可以省略。
返回值:
Lambda表达式的返回值是在箭头后,但是一般可以省略不写,编译器会根据return 语句返回的内容,自动确定返回的类型,但是如果返回的是自定义类型的数据,则需要写明返回值类型。
#include<iostream>
using namespace std;
int p;
class test {
int num;
public:
void fun(int x, int y) {
//auto f1 = [num] {return num; };//不知道需要的是哪个对象的num属性
auto f2 = [this] {return num++; };
auto f3 = [this, x, y] {return num + x + y; };
}
};
int main() {
//lambda表达式
// []捕获列表
// []不捕获
// [=]值形式捕获所有外部变量 ,只读
// [&]引用形式捕获所有外部变量,可读可写
// [=,&a]值形式捕获所有外部变量,引用形式捕获a
//
int a;
//auto f1 = [] {return a; };//捕获列表为空,无法访问a
auto f2 = [] {return p; };//可以访问全局变量
auto f3 = [a] {return a; };//值形式捕获a
//auto f4 = [p] {return p; };//不可以捕获带有静态存储性质的变量
auto f5 = [=] {return a; };//值形式捕获所有外部变量
auto f6 = [&] {return a++; };//引用形式捕获所有外部变量
auto f7 = [=, &a] {return a += p; };//值形式捕获所有外部变量,引用形式捕获a
return 0;
}
常见用法
Lambda表达式的本质是函数指针,也是一个匿名的内联函数,所以我们可以在需要函数指针的地方就地定义一个Lambda表达式,这样可以使代码更加连贯,可读性更强。比方说在algorithm头文件中封装好的sort()函数,这个函数的第三个参数是需要一个函数比较器的地址,此时我们就可以就地定义一个Lambda表达式,来实现这个比较器。
#include<iostream>
#include<vector>
#include<algorithm>//sort函数的头文件
using namespace std;
class A {
public:
int num;
string name;
A(int num) {
this->num = num;
}
};
int main() {
vector<A>vec = { A(2),A(-3),A(1),A(3) };
sort(vec.begin(), vec.end(), [](A a, A b) {
return a.num > b.num;
});
for (auto it : vec)cout << it.num << " ";
return 0;
}
熟练的使用Lambda表达式,可以很高效的编写代码,在后期维护和调试中,也可以省去反复查找函数的操作,节省大量时间。