当前位置: 首页 > news >正文

【C++11特性】Lambda表达式(匿名函数)

一、函数对象

在C++中,我们把所有能当作函数使用的对象当作函数对象。
一般来说,如果我们列出一个对象,而它的后面又跟有由花括号包裹的参数列表,就像fun(arg1, arg2, …),这个对象就被称为函数对象。函数对象大致可分为以下几类:

1)函数类

函数类,即重载了()括号操作符。
在这里插入图片描述

其可以直接通过该类对象 val()调用,其与直接定义val()效果一致。
在这里插入图片描述
优势:

a) 函数对象的类是我们自定义的,所以类中可以自定义状态变量,该函数对象多次调用过程中可以共享该状态,灵活度比函数调用更高。
b) 函数对象有自己特有的类型,而普通函数无类型可言。因此我们在使用STL的时候,可以传递相应类型作为参数来实例化模版,实现我们自己的规则。

2)Lambda

2.1、概述:

C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。
在QT之前的总结中,我们可以知道其是通过外部的 [ ] 来明确函数体内部可以访问的外部变量,这个过程称为Lambda表达式 “捕获” 了外部变量。
类似参数传递方式(值传递、引入传递、指针传递),在Lambda表达式中,外部变量的捕获方式也有值捕获、引用捕获、隐式捕获。

语法格式:

[函数对象参数] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

a.函数对象参数:
表示Lambda表达式开始,这部分必须存在。[ ] 中引用的变量,称作闭包。
函数对象参数具体有以下形式:
在这里插入图片描述

b.操作符重载函数参数:
标识重载的 () 操作符的参数,没有参数时,这部分可以省略。参数可以通过
按值(如: (a, b))和按引用 (如: (&a, &b)) 两种方式进行传递。

c.mutable 或 exception 声明
这部分可以省略。添加mutable修饰,可以修改传递进来的拷贝。而
exceptions声明用来指定函数抛出异常,感觉用得比较少。

d.-> 返回值类型
标识函数返回值的类型,当返回值为 void,或者函数体中只有一处 return 的
地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

e.{函数体}
可为空,但不可省略。

2.2、实例应用:

在这里插入图片描述

【注:图中实例暂未运行成功,不知道是不是没有按照C++11编译】
这样的代码编译的时候,lambda会自动生成一个类,其的成员变量对应每一个捕获到的变量,这跟上面说道的函数类类似,如下图:
在这里插入图片描述

3)std : : function类

当需要一个非模版函数对象作为类的成员或函数参数时,你必须指定函数对象的具体类型,C++没有这样的基类,但标准库中提供了一个模版类std::function来代表所有函数对象。
在这里插入图片描述

std::function抽象了函数对象的类型和参数,因此无论普通函数,还是函数指针、lambdas,又或是任何可以被当做函数使用的对象,只要拥有相同参数和返回值,均可以用同一类std::function表示。
尽管std::function非常有用,但是它也带来了性能损失。这是因为为了隐藏包含的函数对象类型,提供通用的调用接口,std::function使用了叫做type erasure(类型擦除)的技术。
简单来说是通过虚函数的调用在运行期来决定具体调用,因此编译器无法内联(inline)函数调用,也无法进行更多优化。

【注:类型擦除在后续文章中总结。】

实例:
在这里插入图片描述

4)std : : bind(参数绑定)和闭包

大多数的编程范式都提供了提高代码重用的方式,比如在面向对象编程中,我们可以通过抽象出特定类来将复杂系统拆分成小的组件,在降低耦合的同时也可以分开设计、测试代码。
而在函数式编程中,我们可以通过标准库std::bind来创造闭包。
在这里插入图片描述

std::bind返回一个基于f的函数对象,其参数被绑定到args上。f的参数要么被绑定到值,要么被绑定到placeholders(占位符,如_1, _2, …, _n)。
通过std::bind,我们可以为同一个类的不同对象分配不同的实现,从而实现不同的行为。这种方式使得我们不需要设计继承和多态的架构,为程序库设计提供了新方式。

【注:程序库的设计不应该给使用者带来不必要的耦合,而继承是排名第二的耦合方式,最强耦合是友元…】

相关文章:

  • 职坐标IT培训破局AI风口新赛道
  • 「Mac畅玩AIGC与多模态06」开发篇02 - 开发第一个知识库问答应用
  • MANIPTRANS:通过残差学习实现高效的灵巧双手操作迁移
  • MYSQL-OCP官方课程学习截图
  • K8s新手系列之K8s中的资源
  • 庙算兵棋推演AI开发初探(7-神经网络训练与评估概述)
  • springboot dev process
  • 每日算法-250428
  • 从千兆到40G:飞速(FS)助力制造企业构建高可靠智能生产网络
  • 【JavaScript】相等运算符、条件运算符
  • 爱芯元智/芯昇,XS9950A,1 通道AHD模拟视频
  • 02 面向对象
  • 游戏盾与高防CDN的协同防御策略分析
  • 网络准入控制系统推荐:2025年构建企业网络安全的第一道防线
  • 【深度学习】#10 注意力机制
  • MQ-2烟雾传感器
  • 基于 BERT 微调一个意图识别(Intent Classification)模型
  • 在前端应用领域驱动设计(DDD):必要性、挑战与实践指南
  • 2025三掌柜赠书活动第十五期:高并发系统:设计原理与实践
  • GRPO有什么缺点,如何改进?
  • 今年一季度全国社会物流总额达91万亿元,工业品比重超八成
  • 上海浦东单价超10万楼盘228套房源开盘当天售罄,4月已有三个新盘“日光”
  • 人民日报社论:做新时代挺膺担当的奋斗者
  • 报告:到2030年我国无人机产业将率先实现万亿规模
  • 美国政府将暂时恢复部分受影响留学生的合法身份,并将制订新标准
  • 申花四连胜领跑中超联赛,下轮榜首大战对蓉城将是硬仗考验