STL(1) - Lambda表达式

知识不能浅尝辄止,需用耐心得其精华。这里就先作为我学习道路上的笔记吧。

先介绍一下“谓词”,“谓词”是一个可以调用的表达式,它可以作为一个函数的参数。STL中所用的谓词分为两种:一种是一元谓词,即它接受一个参数,另一种是二元谓词,即它接受两个参数。以谓词作为参数的函数或者算法对输入序列中的元素调用此谓词。
这里的lambda表达是就是一个谓词,它是一个可以调用的代码单元,相当于一个未命名的内联函数。与任何其他函数类似,其具有一个参数列表,一个返回类型,一个函数体。其具有以下形式:
[capture list] (parameter list) -> return type { function body}
其由捕获列表(其所在函数中定义的局部变量的列表)、参数列表、返回类型和函数体组成。它的返回类型是使用尾置返回的。
我们在使用时可以选择忽略参数列表和返回类型但必须包含捕获列表和函数体。
以下是最简单的lambda函数:

auto func=[]{ return 99;};
func();

lambda函数的调用和其他普通函数一样,都是使用调用运算符。在这里忽略括号和参数列表相当于指定一个空参数列表。忽略了返回类型,lambda根据函数体中的代码推断出返回类型,若只是一个return语句或着没有,则返回void。
给lambda传递参数
lambda表达式中的参数不能含有默认参数。lambda调用的实参数目和形参数目相等。

auto func=[](const int a,const int b){ return a+b;};
cout<<func(1,2)<<endl;

这里函数输出为 3 。
使用捕获列表
lambda表达式捕获所在函数中的局部变量,通过在捕获列表中指明将要使用的局部变量,指引lambda在其内部包含访问局部变量所需的信息。不同的捕获变量用“,”分隔开来。

int a=100;
int b=50;
auto comp=[a](const int b){ return a>b; };
auto add=[a,b]{ return a+b;};
cout<<comp(20)<<endl;
cout<<add()<<endl;

类似参数传递,变量的捕获方式可以是值传递或值引用。此种方式是值传递的方式,被传递对象应该是可以拷贝的类型。
以下是值引用方式

int a=100;
auto comp=[&a](const int b){ return a>b;};
cout<<comp(20)<<endl;

隐式捕获
除了显式捕获,还可以隐式捕获局部参数。可以让编译器根据lambda表达式中的代码推断出我们使用的局部变量。为了指示编译器推断出我们使用的局部变量,我们应该在捕获列表中写一个“&”或“=”,“&”告诉编译器采用引用捕获,“=”告诉编译器采用值传递捕获。也可混合使用隐式捕获和显式捕获。

int a=20;
int b=80;
auto fun1=[&]{ return a; };
auto fun2=[=]{ return b; };
auto fun1=[&,b]{ return a+b; };
auto fun2=[=,b]{ return a+b; };

在使用混合捕获方式时,捕获列表的第一个元素必须是&或=,此符号指定了默认的捕获方式。并且显式捕获的变量必须使用与隐时捕获不同的方式。即隐式捕获是引用,那么显式捕获需是值传递,若隐式捕获是值,那么显式捕获需是引用。
可改变值的lambda
在引用捕获的情况下可以在lambda函数体中改变变量的值,但在值捕获的情况下是不能改变变量的值的,这时可以添加关键字mutable。

int a=7;
int b=8;
auto func=[a,&b] { cout<<a<<endl;
          cout<<b<<endl;
          a++;   //wrong
          b++;  //right  };
auto func1=[a] () mutable { cout<<a<<endl;
                            a++;   //OK
                            };

指定返回类型
可以使用符号”->”指定返回类型。也可在参数列表和函数体之间指定异常。

auto fun=[] () ->int { return 100;};

新标准
(1) 在C++14新的标准特性中,lambda表达式加入了可以推断类型的新特性。在C++11中lambda表达式的形式参数必须为具体的类型,而C++14中,其形参可以是auto修饰的。

auto fun=[](auto a,auto b){ return a+b;};

(2) C++11的捕获方式为值拷贝或者值引用的方式,捕获已经在外层作用域声明的变量,这说明其不可以捕获move-only的类型,但在C++14中捕获的变量可以是任意表达式初始化,可以任意声明lambda变量,而不需在外层作用域中声明相应名字的变量,其可以是capture by value-move。

auto fun=[value=9+7]{ return value;};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值