Lambda 介绍
Lambda 函数也叫匿名函数, 是C++ 11中新增的特性;
1. Lambda函数的好处
如果你的代码里面存在大量的小函数,而这些函数一般只被调用一次,那么将他们重构成 lambda 表达式。
Lambda函数使代码变得更加紧凑、更加结构化和更富有表现力;
lambda在c++作用主要是作为内嵌函数,逻辑更加清楚,代码可读性更好;
例:
void main()
{
thread t1([]() {
printf("hello...");
});
t1.join();
}
2. C++11 的 lambda 表达式规范如下:
此图显示了 lambda 的组成部分:
-
capture 子句(在 C++ 规范中也称为 Lambda 引导。)
-
参数列表(可选)。 (也称为 Lambda 声明符)
-
mutable 规范(可选)。
-
exception-specification(可选)。
-
trailing-return-type(可选)。
-
Lambda 体。
具体见:
C++ 中的 Lambda 表达式 | Microsoft Learn
Lambda 表达式的定义形式如下:
[外部变量访问方式说明符] (参数表) -> 返回值类型
{
语句块
}
example
[=] (int x, int y) -> bool {return x%10 < y%10; }
Lambda捕获列表
Lambda表达式与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据;
语法上,在“[]
”包括起来的是捕获列表
捕获列表由多个捕获项组成,并以逗号分隔。捕获列表有以下几种形式:
[]
表示不捕获任何变量
[var]
表示值传递方式捕获变量var
int num = 100;
auto function = ([num]{
std::cout << num << std::endl;
}
);
[&var]表示引用传递捕捉变量var (可修改值)
[=]
表示值传递方式捕获所有父作用域的变量(包括this
)
[=, &a, &b]
表示以引用传递的方式捕捉变量a
和b
,以值传递方式捕捉其它所有变量
[&, a, this]
表示以值传递的方式捕捉变量a
和this
,引用传递方式捕捉其它所有变量。
不过值得注意的是,捕捉列表不允许变量重复传递。下面一些例子就是典型的重复,会导致编译时期的错误。例如:
[=,a]这里已经以值传递方式捕捉了所有变量,但是重复捕捉a了,会报错的;
[&,&this]这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复。
Lambda参数列表
Lambda还可以接受输入参数。参数列表是可选的, 类似于函数的参数列表
auto function = [] (int a, int b){
return a+ b;
};
function(100, 200);
可变规格mutable
默认情况下Lambda函数总是一个const
函数,mutable
可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
#include <iostream>
using namespace std;
int main()
{
int m = 5;
[&] (int a) mutable { m += a; }(6); // a=6;
cout << m << endl;
}
输出 11;
返回类型
Lambda表达式的返回类型会自动推导。除非你指定了返回类型,否则不必使用关键字
auto x1 = [](int i){ return i; };
Lambda表达式的缺点
- Lamdba表达式语法比较灵活,增加了阅读代码的难度
- 对于函数复用无能为力
Lamdba 表达式应用于STL算法库
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[4] = { 1, 2, 3, 4 };
int total = 0;
for_each(a, a + 4, [&](int & x) { total += x; cout << total << endl; });
cout << total << endl; //输出 10
return 0;
}