C++ 中的可调用对象

目录

一.可调用对象简介

1.什么是可调用对象?

2.可调用对象有什么用?

二.函数指针和仿函数

1.函数指针

a.函数指针的使用语法

b.函数指针的应用场景

2.仿函数

a.仿函数的基本概念

b.仿函数的优点

三.lambda表达式和function

1.lambda表达式

a.基本语法格式

b.lambda表达式的实战实例

2.function

a.使用方法

b.应用场景和注意事项


一.可调用对象简介

1.什么是可调用对象?

可调用对象指的是任何可以像函数那样被调用的实体。这些实体包括普通函数、仿函数对象(即重载了 operator() 的类对象或结构体对象)、函数指针、lambda表达式、以及C++11引入的std::function包装器。

简单来说,可调用对象是一个实体,我们可以对它传递参数,像调用函数一样去调用它。

2.可调用对象有什么用?

以std::sort()排序函数为例,它用于对元素进行排序,通常接受两个或三个参数。前两个参数指定了要排序的范围(通常是容器中的一段),而第三个参数(可选的)是一个比较函数或比较函数对象,用于明确元素排序的规则(如按元素大小排序、按元素字典序排序...等)。

再以std::priority_queue() 容器适配器为例,它提供了一个基于优先级的队列,通常用于管理需要按照优先级顺序处理的元素集合。std::priority_queue() 的构造函数允许你指定其底层容器的类型(虽然这通常是隐式的,默认为 std::vector)、元素的类型以及一个可选的比较函数或函数对象,用于确定元素的优先级。

小结,可调用对象可以:

①作为参数传递(如上述的sort()的第三个参数);

②在标准库中的使用(如上述的优先级队列);

③做回调函数(即在某个事件发生时由系统或其他代码调用的函数);

④自定义比较和排序;

......等。

简单说完了什么是可调用对象,和可调用对象的用途后,咱们来正式了解可调用对象的具体形式吧,它包括函数指针(C语言里的那套)、仿函数、lambda表达式和包装器。咱们来一一认识~~

二.函数指针和仿函数

1.函数指针

函数指针是指向函数的指针变量,它允许我们将函数作为参数传递给其他函数,或者将函数地址存储在变量或容器中以供后续调用。

a.函数指针的使用语法

注意函数指针的声明格式:返回值类型 (*指针名) (函数参数类型)

通过函数指针调用函数?俺直接用函数名调用函数不行吗?为啥要再通过一个指针?是不是感觉有中脱裤子放P的感觉?

暧,上面那个例子只是为了将函数指针的使用规则,但函数指针真正的应用场景肯定不是这样的。

b.函数指针的应用场景

①函数指针作为参数

②函数指针做回调函数

函数指针有多种用途,比如实现回调函数、在数据结构中存储函数以进行自定义操作等。

2.仿函数

a.仿函数的基本概念

仿函数指的是那些重载了 operator() 的对象或类实例,从而使得这些对象或实例可以像函数一样被调用。

例一:

例二:

仿函数对象可以做实参做sort的第三个参数(上述可调用对象简介中有过演示)来指定排序规则,仿函数也可做类型在优先级队列中明确元素的排序规则。

仿函数的核心在于其重载的 operator() 方法,这个方法定义了当仿函数被“调用”时应该执行的操作。由于仿函数实际上是对象,因此它们可以包含状态(即成员变量),这使得它们比传统的函数指针更强大,因为函数指针无法直接携带状态信息。

b.仿函数的优点

①仿函数可以包含并维护自己的状态,这是函数指针所无法做到的。

②与函数指针相比,仿函数提供了更好的类型安全性,因为它们的参数和返回类型在编译时就被确定了。

③由于仿函数的本质是一个类对象,所以仿函数可以通过继承来扩展功能,这是函数指针所不具备的。

④在某些情况下,使用仿函数可以使代码更加清晰和易于理解,特别是当可调用对象的行为与其数据紧密相关时。

三.lambda表达式和function

Lambda表达式允许我们在代码中定义和使用内联的、匿名的函数对象,它们非常适合用于需要小函数的地方。

1.lambda表达式

a.基本语法格式

语法格式:[捕捉列表](参数列表)mutable -> 返回类型 {函数实体};

如:auto less = [ ] (int x, int y) -> bool { return x>y; };   

调用方式:cout << less(1 , 2) <<endl;

捕获列表

[=]:表示以传值的方式捕获所有父作用域中变量和函数(包括tihs);

[&]:表示以传引用的方式捕获所有父作用域中变量和函数(包括this);

例如:[x, &y] 表示捕获x为值,y为引用; 或[=, &z] 表示捕获所有外部变量为值,但z为引用;或 [&, x]  表示捕获所有外部变量为引用,但x为值。

[ ] 空捕获,表示不捕获任何变量或函数。

lambda的捕捉列表可以捕捉到外界的对象,相当于是外界对象的一份拷贝,但其默认被const修饰,如auto swap = [x , y] () { int tmp=x; x=y; y=tmp; }; ×

mutable

而若想改变捕捉的对象,则需要使用到mutable,如:auto swap = [x , y] () mutable { int tmp=x; x=y; y=tmp; }; 但此时x和y虽然能在函数定义内改变,但其仍是外界对象的一份拷贝,其值改变不会影响到外界的对象。

除非是外界对象的引用,如:auto swap = [&x , &y] () { int tmp=x; x=y; y=tmp; };  

参数列表

int x, int y)相当于函数形参,是我们调用该可调用对象时传入的参数;

-> 是固定的语法个数,但可以省略;bool 相当于函数的返回值类型,由于其具体类型可以通过函数实体推导,故该类型也可以省略;

{ return x>y; } 相当于函数实体,是可调用对象需要执行的具体功能。

注意:范围for的底层是迭代器,而lambda的底层是仿函数!!

lambda对象类型

一个lambda语句对应一个实现有仿函数的类,对个lambda对应的类名都不同,类名的生成使用了UUID做后缀,保证类名不会重复!

auto 是可调用对象的类型,它是唯一的、未命名的类型,这种类型是由编译器根据lambda表达式的捕获列表、参数列表、返回类型以及函数体自动生成的,故只能用auto来自动推导(或function包装器)。

b.lambda表达式的实战实例

示例一(捕获父作用域中的局部变量、全局变量和函数体):

示例二(捕获父作用域中的类对象):

2.function

std::function 是一个功能强大的模板类,它提供了一种通用的、类型安全的方式来存储和调用任何可调用对象,包括普通函数、Lambda表达式、仿函数对象以及成员函数指针。

a.使用方法

定义一个 std::function 实例时,需要指定可调用对象的返回类型和参数类型

function对各类可调用对象的封装:

b.应用场景和注意事项

应用场景

①回调函数:在需要传递回调函数作为参数的场合,function 可以提供一种灵活且类型安全的方式。

②事件处理:在基于事件驱动的应用程序中,function 可以用于注册事件处理器。

注意事项

空 function :未初始化的 function 是空的,调用它会抛出 std::bad_function_call 异常。

多线程:function 本身不是线程安全的,但如果它所存储的可调用对象是线程安全的,那么可以在多个线程中安全地调用它。

性能:虽然 function 提供了很大的灵活性,但它通常比直接调用函数或Lambda表达式要慢一些,因为它涉及到额外的间接调用和类型擦除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/903196.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

完全了解一个asp.net core MVC项目模板

当我们使用Visual Studio 2022去新建一个基于asp.net core Web项目的时候&#xff0c;一般有三种选择&#xff0c;一种是空项目&#xff0c;一种是基于MVC的项目、再有一种就是基于包含Razor Pages实例的web应用。如下图&#xff1a; 今天&#xff0c;我们打算选择基于MVC模…

《MYSQL 实战45讲》 慢查询产生的原因

一.查询长时间不返回的原因 首先要执行下show processlist来查看各个线程的状态&#xff08;是否在等待锁&#xff09; 1.DML写锁导致其他线程对改表的读取被阻塞 当一个线程正在持有t表的DML写锁时&#xff0c;其他线程查询语句就会被阻塞&#xff0c;一直等到DML写锁释放才…

RWA“两链一桥”平台在香港金融科技周亮相

第九届香港金融科技周今日开幕&#xff0c;记者在主题为Trust Bridge的论坛上获悉&#xff0c;蚂蚁数科旗下蚂蚁链在此次金融科技周首次公开了其为RWA业务打造的“两链一桥”平台&#xff0c;旨在帮助更多内地新能源资产赴港RWA&#xff0c;实现技术赋能实体资产。 “两链一桥“…

MySQL8 安装配置及卸载教程

MySQL8 安装配置及卸载教程 0 卸载 MySQL 如果之前没安过 MySQL &#xff0c;或者卸载干净了不用看这个。 如果安装中出现以下问题&#xff0c;有可能是为之前安装 MySQL 不成功&#xff0c;有残留的安装程序等文件程序或者是卸载 MySQL 不成功。 0.1 停止服务 首先进入服务…

LabVIEW航空发动机测试系统

随着航空工业的快速发展&#xff0c;发动机性能的测试与优化成为确保航空安全的关键任务。针对日益复杂的性能需求&#xff0c;开发了一套基于LabVIEW的航空发动机测试系统&#xff0c;能够进行精确的性能评估与实时数据分析。系统将软件与硬件深度结合&#xff0c;实现了自动化…

容联云容犀Copilot&Agent荣获「2024中国大模型应用之星」

近日&#xff0c;2024中国智能应用发展大会于北京举行&#xff0c;容联云凭借大模型应用——容犀Copilot&#xff06;Agent在大模型应用领域的卓越表现和标杆案例&#xff0c;荣获“2024中国大模型应用之星奖”。 中国软件网CEO、海比研究院院长曹开彬在开场致辞中明确指出&…

建筑行业知识管理:构建高效文档管理系统,提升项目协作与管控能力

各行各业都在经历数字化转型&#xff0c;建筑行业也不例外&#xff0c;正经历着前所未有的变革。随着工程项目规模的扩大和复杂性的增加&#xff0c;传统的管理方式已难以满足高效协作和精准管控的需求。因此&#xff0c;构建一个高效的在线AI知识库管理系统&#xff0c;成为提…

【STM32】SD卡

(一)常用卡的认识 在学习这个内容之前&#xff0c;作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解&#xff0c;晕头转向。 SD卡&#xff1a;Secure Digital Card的英文缩写&#xff0c;直译就是“安全数字卡”。一般用于大一些的电子设备比如&#xff1a;电脑、数码相机、AV…

【视频】Camera结构详解

1、爆炸图 先看几张爆炸图: lens:镜头 VCM:音圈马达 Voice coil motor Mount :固定座 IR Filter:滤光片 Sensor:感光传感器(图像传感器) Substrate:基板 FPC:柔性印制电路板 2、镜头 镜头是仅次于Sensor芯片影响画质的第二要素,其组成是透镜结构,由几片透镜组…

使用微信免费的内容安全识别接口,UGC场景开发检测违规内容功能

大家好&#xff0c;我是小悟。 内容安全识别主要针对的是有UGC即用户生成内容的功能场景&#xff0c;通过结合内容安全的审核能力&#xff0c;应对文本、图片、音频内容类型下的敏感内容识别、涉黄内容识别、暴恐内容识别、辱骂内容识别等违规问题&#xff0c;可以提高审核效率…

UE5 射线折射

这个判断是否有标签是需要带有此标签的Actor来反射

【PnP】详细公式推导,使用DLT直接线性变换法求解相机外参

文章目录 &#x1f680;PnP1️⃣ 求解不考虑尺度的解2️⃣ 恢复解的尺度 &#x1f680;PnP PnP(Perspective-n-Point)是求解3D到2D点相机外参的算法。PnP算法有DLT直接线性变换、P3P三对点估计位姿、EPnP(Efficient PnP)、BA(Bundle Adjustment)光速法平差。这里主要讲解DLT。…

二十四、Python基础语法(变量进阶)

一、引用 在定义变量的时候, 解释器会给变量和数据分别在内存中分配内存&#xff0c;变量中保存的是数据的地址, 称为引用&#xff0c;Python 中数据的传递,传递的都是引用&#xff0c;可以使用 id(变量) 函数,获取变量中引用地址。 # 将数字1在内存中的地址储存到变量a中 a …

Ubuntu18.04安装vscode1.94.2失败安装vscode1.84.2

系统环境&#xff1a;Ubuntu18.04.6 LTS 自己先去vscode官网下载好最新版本的vscode1.94.2&#xff08;不下也行&#xff0c;反正最新版也用不了&#xff0c;哈哈&#xff09; 网址&#xff1a;Visual Studio Code - Code Editing. RedefinedVisual Studio Code is a code ed…

《编程并不难:像学语文一样学习编程语言》

《编程并不难&#xff1a;像学语文一样学习编程语言》 一、编程为何被认为难&#xff08;一&#xff09;编程语言的难点&#xff08;二&#xff09;逻辑思维的挑战&#xff08;三&#xff09;抽象思维的要求&#xff08;四&#xff09;学习曲线的陡峭&#xff08;五&#xff09…

大数据-194 数据挖掘 机器学习理论 有监督、无监督、半监督、强化学习

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

argparse的基本用法

目录 前言 一、代码示例 二、三种给定形参的方式 1.修改运行配置 配置形参​编辑 2.cmd给定形参 给定形参 3.pycharm终端给定形参 三、获取argparse帮助信息 前言 argparse 是 Python 标准库中的一个模块&#xff0c;用于解析命令行参数。它使得程序能够通过命令行接…

大模型低资源部署策略

文章目录 解码效率分析大模型训练后量化方法经验性分析与相关结论由于大模型的参数量巨大,在解码阶段需要占用大量的显存资源,因而在实际应用中的部署代价非常高。在本文中,我们将介绍一种常用的模型压缩方法,即模型量化(ModelQuantization),来减少大模型的显存占用,从…

MicroServer Gen8再玩 OCP万兆光口+IT直通之二

这个接上一篇&#xff0c;来个简单测试。 一、测试环境 PC端&#xff1a;Win10&#xff0c;网卡&#xff1a;万兆光纤&#xff08;做都做了&#xff0c;都给接上&#xff09;&#xff0c;硬盘使用N年的三星SSD 840 交换机&#xff1a;磊科GS10&#xff0c;带两个万兆口 Gen…

Python: Print Table on console

# encoding: utf-8 # 版权所有 2024 ©涂聚文有限公司 # 许可信息查看&#xff1a; # 描述&#xff1a; # Author : geovindu,Geovin Du 涂聚文. # IDE : PyCharm 2023.1 python 3.11 # OS : windows 10 # Datetime : 2024/10/28 22:08 # User : geo…