1、定义解析
Lambda表达式,顾名思义,它是一个表达式,和常规函数表达式不同的是它是“匿名”的,也就是没有函数名的表达式(简称匿名表达式)。
2、Lambda的一般表达形式
capture list :捕获列表,是lambda所在的函数中定义的局部变量的列表(通常为空)
parameter list:参数列表
return type:返回类型
function body:函数体
说明:(1)外观来看,和普通函数类似的是,Lambda表达式具有一个返回类型,一个参数列表,一个函数体;不同的是它少了函数名,多了一个捕获列表。同时,Lambda必须使用尾置返回来指定返回类型。下面通过几个例子进行讲解
(2)和函数体不同,Lambda可能定义在函数内部
(3)我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体(捕获列表可以为空,但是'[ ]'不能省)
3、举例
(1)介绍Lambda
可见,lambda的调用方式,和普通函数一样,都是调用运算符。
在该lambda中,忽略括号中的参数列表等价于指定一个空参数列表。在此例中,当调用 f 时,参数列表是空的。如果忽略返回类型,Lambda根据函数体中的代码推断出返回类型。如果函数体只有一个return语句,则返回类型从返回的表达式的类型推断而来。否则,返回类型为空
(2)向Lambda传递参数
我们使用排序算法来试一下:
其中,捕获列表为空,a和b表示形参,当调用stable_sort函数时,遍历容器words的元素时给a和b进行传参,依照lambda表达式中运算规则返回true或者false,来决定a、b谁大谁小。
(3)使用值捕获列表
上面例子还没有使用过捕获列表,这里在调用find_if标准库函数的时候用一下。
int sz = 2;
vector<string> words={"123", "23", "456"};
也就是说sz的值是从前面获取的(注意不要超出变量的作用域),这里wc的结果就是找到words中第一个大于2的元素下标。
Lambda表达式中捕获列表的捕获类型分为值捕获和引用捕获两种。下面分别进行介绍。
3.1值捕获
3.2引用捕获
(4)多参数
我们的捕获列表还可以是多参数,甚至流操作(注意,stream只能传引用:流对象中含有指向IO缓冲区的指针,假如流对象可以复制,那么将会有两个指针同时操作缓冲区,如何释放、如何修改都会有冲突同步问题,因此流对象无法复制。)
除了上面显式列出我们使用的函数内的变量的捕获参数方式外,也可以让其自己推导使用了哪些变量,也就是”隐式捕获“。
4、隐式捕获
隐式捕获也有两种方式,值(=)和引用(&)
(1)值捕获
结果就是sz的值会在前面定义的变量sz中去找
(2)引用捕获
类似值捕获,不举例了。
如果混合使用隐式捕获和显式捕获: