lambda

1.为什么需要有lamdba?

:很多泛型算法都有一个允许我们传递可调用对象(或可调用表达式)的版本(我们将这个可调用的对象或表达式暂称为谓词),例如:版本一ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last) ,版本二ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last, BinaryPredicate binary_pred)。可调用对象(或可调用表达式)包括重载了调用运算符的类,函数,指向函数的指针,以及lambda。但是泛型算法对谓词的参数个数有限制(只有一元谓词或二元谓词),lambda就是为了解决这个限制。


2.介绍lamdba

[capture list]  (parameter list)   ->return type { function body; }

capture list::捕获列表,由于lambda可能定义在函数内部,捕获列表就是一个lambda所在函数中定义的局部变量的列表,lamdba通过将局部变量包含在其捕获类表中来指出将会使用这些变量,捕获列表只能用于局部非static变量;lambda可以直接使用定义在当前函数之外的名字和局部static变量;

parameter list:参数列表,lamdba不能有默认实参

return type:返回类型,必须使用置尾返回

function body:函数体

可以忽略参数列表和返回类型,但是必须永远包含捕获列表和函数体。如果忽略返回类型,lamdba根据函数体中的代码推断返回类型:如果函数体只有个return一条语句,则返回类型从返回的表达式的类型推断而来,否则,返回类型为空。


3.为什么lambda具有以上特性?
其实在定义一个lamdba时,编译器会生成一个与lamdba对应的新的(未命名的)类类型。当向一个函数传递一个lambda时,同时定义了一个新类型和该类型的一个对象:传递的参数就是编译器生成的类类型的未命名对象。类似的,当使用auto定义一个用lamdba初始化的变量时,定义了一个从lamdba生成的类型的对象。默认情况下,通过lamdba生成的类都包含一个对应该lamdba所捕获的变量的数据成员,类似任何普通类的数据成员,lamdba的数据成员在lamdba对象创建时被初始化。


4.捕获列表

值捕获:采用值捕获的前提是对象可以拷贝。被捕获的变量的值是在lamdba创建时拷贝,而不是调用时拷贝,因此随后对被捕获变量的修改不会影响到lamdba内对应的值。

引用捕获:一个以引用方式捕获的变量与其他任何类型的引用行为类似。当我们在lamdba函数体中使用此变量时,实际上使用的是引用所绑定的对象。引用捕获的主要限制是:必须确保被引用的对象在lamdba执行时是存在的。lamdba不活的都是局部变量,这些变量在函数结束后就不存在了。如果lamdba可能在函数结束后执行,捕获的引用指向的局部变量就消失了。我么可以从一个函数返回lamdba,与函数不能返回一个局部变量的引用类似,此lamdba也不能包含引用捕获。

隐式捕获/显式捕获:让编译器根据lamdba函数体中的代码来推断我们要使用哪些变量,此时我们应该在捕获列表中写一个&(捕获引用方式)或=(采用值捕获方式)。


5.可变lamdba

值捕获变量:默认情况下,对于一个值被拷贝的变量,lamdba不会改变其值。如果我们希望能改变一个被捕获的变量的值,就必须在参数列表与函数体之间加上关键字mutable。

引用捕获方式:一个引用捕获的变量是否可以修改依赖于引用指向的变量是一个const类型还是非const类型。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值