栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Java

【C++】超详细入门——lambda表达式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【C++】超详细入门——lambda表达式

lambda表达式
  • 1、可调用对象
  • 2、谓词
  • 3、尾置返回类型
  • 4、lambda表达式
    • 4.1无参lambda表达式
    • 4.2有参lambda表达式
    • 4.3使用capture list


1、可调用对象

如果一个对象或表达式可以使用调用运算符(()),则可以称它为可调用对象。

可调用对象共有四种:

  • 函数
  • 函数指针
  • 重载了函数调用运算符的类
  • lambda表达式

可调用对象用途很广,包括在调用泛型算法函数(sort(),find_if()等)时,可以传入可调用对象,来指明泛型算法要对指定范围内的元素进行哪种操作。


2、谓词

再来看一下谓词的概念。

谓词是一个可调用的表达式,其返回结果是一个能用作条件的值。标准库算法所使用的的谓词分两类:

  • 一元谓词:只接受单一参数。
  • 二元谓词:接受两个参数。

一般来说,可调用对象在泛型算法中都被用作谓词传入函数。可以说谓词是可调用对象的一种,也可以说可调用对象可以当做谓词。


3、尾置返回类型

介绍lambda表达式之前,最后再引入一个概念:尾置返回类型。

C++11 中尾置返回类型用来简化函数声明,以一个跟在形参列表后面的 -> 开头,函数名前需要用 auto 来表明该函数的返回类型是用尾置返回类型表示的。

尾置返回类型尤其对于返回类型比较复杂的函数最有效,比如数组的指针或数组的引用:

//返回整型数组指针的函数,形参为一个int。
int (*func(int i))[10];
//使用类型别名
auto func(int i) -> int (*)[10];

这样看来使用类型别名声明复杂函数就更简洁明了吧。


4、lambda表达式

终于到它了——lambda表达式。

lambda表达式又称匿名函数,可以把他理解为未命名的内联函数。它必须使用尾置返回类型来定义,其定义形式为:

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

各部分解释:
capture list:是 lambda 所在函数中定义的局部变量的列表(一般不用);
return type:返回类型;
parameter list:参数列表;
function body:函数体。

4.1无参lambda表达式

lambda表达式中可以忽略参数列表和返回类型,忽略参数列表相当于空参数列表,忽略返回类型可以从 return 语句中推断出返回类型:

例子:

auto f = [] {return 0;};
auto f = [] () -> int {return 0;};  //等价定义
cout << f() << endl;

这里定义了一个可调用对象 f,不接受参数,返回 0。

4.2有参lambda表达式

与普通函数一样 lambda 的形参使用实参初始化。实参和形参的类型必须匹配,而且不能有默认参数。

例一:

bool is_shorter(const string &s1, const string &s2){
    return s1.size()return a.size() < b.size();});//等价定义

接受二元谓词的 sort 用传入的谓词替代 < 操作。

第一个 sort 中把 is_shorter 函数作为二元谓词传入,将 vector 按照字符串长度排序。
第二个把 lambda 表达式作为二元谓词传入,与上一个等价。

例二:

bool is_large(const string &s, string::size_type sz){
    return s.size() > sz;
}
auto iter = find_if(words.begin(), words.end(), is_large);
auto iter = find_if(words.begin(), words.end(), 
	[](const string &s, string::size_type sz){return s.size() > sz;})

这段代码看似是返回 vector 中指向第一个长度大于 sz 的元素的迭代器,但是编译起来却会报错,这是因为 find_if 接受的参数是一元谓词,这里的 is_large 却是二元谓词。

别着急,利用capture list可以解决传入多个参数的问题。

4.3使用capture list

当 lambda 表达式出现在函数中,就可以使用函数中的局部变量,我们需要通过 capture list 指出将会使用的变量。

这样我们就可以直接使用局部变量 sz,而不用通过传参使用它了:

string::size_type sz = 5;
auto iter = find_if(words.begin(), words.end(), 
	[sz](const string &s, string::size_type sz){return s.size() > sz;})

到此 lambda 表达式的讲解就结束了,从今天开始更新 C++ 的基础知识,后面应该会讲解一下标准容器,并手动实现。
希望大家多多关注,三连支持。你们的支持是我源源不断创作的动力。

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1038917.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号