| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C++ Primer笔记——lambda表达式与bind函数 -> 正文阅读 |
|
[C++知识库]C++ Primer笔记——lambda表达式与bind函数 |
目录 一.lambda介绍(一).总体介绍lambda是C++11所规定的一种新方法。一般用于泛型算法传递自定义函数。 其形式如下:
lambda表达式会返回一个函数对象。 举个例子:
实际开发中,一般用于给算法传仿函数,比如:
使用lambda表达式时,有几点需要注意: 1.捕捉列表可以为空 2.尾置返回类型和参数列表可以忽略,即[]{}; 3.捕捉列表和函数体不能忽略。 (二).参数列表使用参数列表时,按照普通函数的参数列表使用即可,唯一的不同是不能有缺省参数。 因此,lambda的实参数量永远与形参保持一致。? 当然,参数可以是引用、指针类型,const修饰也没问题。 (三).尾置返回与普通函数不同,lambda只能使用尾置返回类型,如果忽略尾置返回,那么编译器会自行推断返回类型,当然这个推断也是有条件的: 1.函数体没有return语句,自动推断为void类型,即无需返回。 2.只有一条return语句,根据return类型推断返回类型。 3.多条return语句,返回void(实际上在vs环境下也会根据return自行推到返回类型) (四).捕捉列表顾名思义,捕捉列表就是捕捉已存在的局部变量,因此使用捕捉列表必须捕捉那些已存在且可访问的对象。 同时,即便lambda在函数作用域内,如果没有进行捕捉或列表传参,那么也不能直接使用该变量。 尤其需要注意的是,捕捉列表只能捕捉临时变量,static、全局变量因为具有静态属性不能捕捉。 即声明周期不随函数作用域的变量不能捕捉,因为静态变量本来就可以直接使用自然不需要捕捉。 示例如下:
?当然捕捉也分三种情况: ①值捕捉默认情况下,捕捉列表按照传值的方式捕捉变量,因此,传递给lambda的并不是变量本身,而是变量的一份拷贝,lambda的修改不会影响变量本身。 ②引用捕捉在捕捉参数前加上&即引用捕捉。 在这种情况下,传递给lambda的即是变量本身,当在lambda函数体中进行修改时,变量本身也进行修改。 引用捕捉的常用场景是那些拷贝代价很大的对象,或者不支持拷贝的对象,比如iostream对象就不支持拷贝,只能引用捕捉。 ③隐式捕捉除了可以显式捕捉变量的方式外,还可以使用=或&进行隐式捕捉。 使用=是值捕捉,使用&是引用捕捉。
使用时,隐式捕捉可以和显式捕捉(值、引用捕捉)混合使用,但是有如下要求: 1.隐式捕捉必须在捕捉列表第一个位置。 2.定义的隐式捕捉方式即是指定默认捕捉方式,捕捉列表后续参数默认该方式捕捉。 3.后续显式捕捉的方式必须和隐式捕捉不同。
?(五).lambda与捕捉列表的本质《C++ Primer》中指出,lambda本质是一个函数对象,或者是仿函数。默认情况下,只有一个operator()函数,没有默认构造、赋值、析构函数。 当我们使用lambda时,会生成一个未命名对象,使用时通过该对象调用重载的()完成函数功能。 大致如下:
当使用捕捉列表时,情况分为两种: 1.按引用捕捉,编译器会将捕捉对象直接在类内使用,无需定义成员。 2.按值捕捉,因为有拷贝的发生,不能直接使用捕捉的对象。 此时,lambda类会定义一个带参的构造函数并在类内定义值捕捉的成员变量。构造函数使用值捕捉对象给成员变量赋值。
lambda是否具有构造、拷贝构造、析构函数,要看具体捕捉成员类型而定。 二. 参数绑定bind(一).什么情况下会用bind以find_if函数举例,其传入的第三个是函数对象,且函数参数只能有一个。 但加入我们需要两个参数呢,比如想通过比较来判断是否是要找的值呢?
这种情况下,可以通过使用lambda表达式解决,将j传进捕捉列表。
但是,如果我们就想用judge函数代替lambda呢😂,使用bing参数绑定。 (二).使用方式bind函数定义在头文件<functional>中。 使用形式为:
其中返回类型为_Binder类(vs环境下),但具体函数会有具体的类型,因为_Binder是类模板。 ①参数列表?...省略符所代表的就是函数参数列表,其中需要直接绑定给函数的在bind中给出,需要使用函数传参的使用占位符代替。 占位符在placeholders命名空间中,placeholders又在std中。 占位符使用时如下:
以judge为例,使用bind函数方式如下:
②参数顺序占位符表示的参数,不受出现顺序限制。 比如如下函数:
当调用x和y时可以表示成下面情况:
?即_1占位符表示的永远是函数第一个需要传入的参数,与bind中位置无关。 但是bind中直接绑定的参数,与函数中对应位置绑定。 ③引用类型参数如果函数参数是引用类型呢,比如传递iostream对象(禁止拷贝)。 那么bind中需要绑定引用类型参数,就要使用标准库中的ref函数。
?参考书籍: 《C++ Primer》P349-P357、P507-P509 一个好的程序员应该是那种过单行线都要往两边看的人———Doug Linder 如有错误,敬请斧正? |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/22 19:39:05- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |