lambda表达式
用法简介
c++11: 也是一种可调用对象。
lambda表达式,它定义了一个匿名函数,并且可以捕获定范围内的变量。
1 | auto f = [](int a)->int{ |
特点:
- a)是个匿名函数,也可以理解为“可调用的代码单元”,或者理解成未命名的内联函数。
- b)它也有一个返回类型,一个参数列表,一个函数体
- c)与函数不同的是,lambda表达式可以在函数内部定义,这个是常规函数做不到的:
格式:[捕捉列表] (参数列表) ->返回类型函数体};
这是一个返回类型后置这种语法( lambda表达式的返回类型后置是必须的,这个语法就这么规定) ;
因为很多时候lambda表达式返回值特别明显,所以允许lambda表达式返回类型省略,编译器可以自动推导; 但是如果编译器推断不出来的时候需要我们自定义返回类型,否则就会报错。
- 1.没有参数的时候,参数列表可以省略,甚至()也能省略,所以如下格式都合法
1 | auto f1 = []() {return 1;}; |
- 2.捕获列表[]和函数体不能省,必须时刻包含
- 3.lambda调用方法和普通函数相同,都是使用
()
这种函数调用运算符; - 4.lambda表达式可以不返回任何类型,不返回任何类型就是void:
捕获列表
[捕捉列表]
:通过捕获列表来捕获一定范围内的变量,范围是啥意思呢?
1 | int i = 0; |
- [] 不捕获任何变量,但不包括静态局部变量。lambda可以直接使用局部静态变量(局部静态变量是不需要捕获的
- [&] 捕获外部作用域中所有变量,并作为引用在函数体内使用
- [=] 捕获外部作用域中所有变量,并作为副本(按值)在函数中使用,也就是可以用它的值,但不许给它赋值。
- [this] 一般用于类中,捕获当前类中this指针,让lambda表达式有和当前类成员函数同样的访问权限
如果[]中已经使用了&或者=,那么默认就已经使用了this,捕获this的目的就是为了在lmbda中使用成员变量或成员函数 - [变量名] 如果有多个变量,则彼此之间用
,
分隔。[变量名]表示按值捕获变量名代表的变量,同时不捕获其他变量
[&变量名] 按引用捕获变量名代表的变量,同时不捕获其他变量 - [=,&变量名] 按值捕获所有外部变量,但按引用捕获中所指的变量,这里这个=必须写在开头位置,开头这个位置表示默认捕获方式
也就是说,这个捕获列表,第一个位置表示的是默认捕获方式(隐式捕获方式),后续其他的都是显式捕获方式。 - [&,变量名] 按引用来捕获所有外部变量,但按值来捕获变量名所代表的变量,这里这个&必须写在开头位置,
lambda表达式延迟调用分析
1 | int x = 5; |
凡是按值捕获的外部变量,在lambda表达式定义的这个时刻,所有这些外部变量值就被复制了一份存储在lambda中
解决办法就是按引用调用
lambda表达式mutable
mutable 易变的
主要用于按值捕获外部变量的时候,加了mutable 后按值捕获的外部变量也可以进行修改了
1 | int x = 5; |
lambda表达式类型及存储
一种比较特殊的,匿名的,类类型[闭包类)的对象,也就是定义了一个类类型,又生成一个匿名的该类类型的对象
可以认为它是一个带有operator()
的类类型对象,也就是仿函数(函数对象)
lambda表达式这种语法,是我们可以就地定义匿名函数(就地封装短小的功能闭包),我们也可以用std: :function和std::bind来保存和调用lambda表达式
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 fengyun's Blog!
评论