文章目录
一. 为什么要有 lambda 表达式?
在 C++98 中,如果想要对一个数据集合中的元素进行排序,可以使用 std::sort 方法。如果待排序元素为自定义类型,此时需要用户自定义排序时的比较规则:
后面人们开始觉得上面的写法太复杂了:
- 如果每次比较的逻辑不一样,就要去分别实现多个仿函数
- 仿函数命名不规范的话(比如:Cpmpare1、Compare2 这样的),会给编程者带来了极大的不便。因此,在 C++11 语法中引入了 lambda 表达式。
二. 什么是 lambda 表达式?
1. 概述
下面是 lambda 表达式各个部分的说明:
- [capture-list] : 捕捉列表。该列表总是出现在 lambda 表达式的开始位置,它是 lambda 表达式的标识。编译器根据 [ ] 来判断接下来的代码是否为 lambda 表达式,捕捉列表能够捕捉上文作用区中的变量供 lambda 表达式使用。
- (parameters):参数列表。与普通函数的参数列表一致(可以指定参数是传值还是传引用,或者是否是 const),如果不需要参数传递,则可以连同括号一起省略。
- mutable:默认情况下,lambda 表达式的捕捉列表中,传值捕捉到的值都是 const 属性的,使用 mutable 可以取消这些传值捕捉对象的 const 量性。注意使用该修饰符时,参数列表不可省略。
- ->returntype:返回值类型。用追踪返回类型形式声明表达式的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型自动进行推导。
- {statement}:函数体。在该函数体内,除了可以使用参数列表中提供的形参外,还可以使用捕捉列表中,所有捕获到的变量。
注意: 在 lambda 表达式中,参数列表和返回值类型都可以省略不写,而捕捉列表和函数体可以为空,但不能省略不写。因此 C++11 中最简单的 lambda 表达式为:[]{}; 该 lambda 表达式不能做任何事情。
如果我们将 lambda 表达式写全,那便是如下的样子:
接下来,我们分别来看看,组成 lambda 表达式的这几个部分
参数列表 — ( )
示例:使用普通函数和 lambda 表达式,各自实现一个两数相加的功能:
可以看到,两者在使用上是没有区别的
有时,我们的 lambda 表达式不需要传入参数,此时连 ( ) 都可以省略掉:
捕捉列表 — [ ]
lambda 表达式和函数有一个区别是:函数先是在全局域中定义,然后到局部中去使用;而 lambda 表达式,它的定义和使用都在局部中,这个时候 lambda 表达式旁定然会存在着许多局部变量
int main()
{
//函数体里有大量局部变量
int a = 10;
char c = 20;
//lambda 表达式就定义在这些局部变量周围
auto lambda_func = []() {
};
}
为了方便获得他们,lambda 表达式里便引入了一个新的参数列表——捕捉列表,它专门用来捕捉所属局部域中的其它参数,比如:
int main