8. C++ function的介绍和使用

std::function的介绍和使用

std::function是一个可变参类模板,是一个通用的函数包装器(Polymorphic function wrapper)。std::function的实例可以存储、复制和调用任何可复制构造的可调用目标,包括普通函数、成员函数、类对象(重载了operator()的类的对象)、Lambda表达式等。是对C++现有的可调用实体的一种类型安全的包裹(相比而言,函数指针这种可调用实体,是类型不安全的)。

std::function中存储的可调用对象被称之为std::function的目标。若std::function中不含目标,调用不含目标的std::function会抛出std::bad_function_call 异常。

看到这里我们一定会疑惑,std::function到底怎么将可调用目标存储起来的?怎么为不同可调用目标提供通用的“包装”?

我们将这些疑问暂时放下,先看一下如何使用std::function。

std::function源码分析

std::function模板类的定义如下,有一个标准函数指针类型的成员变量_M_invoker。

std::function涉及到的几个类之间的简化关系:

图片

  • function的函数指针成员变量_M_invoker被初始化为_Function_handler的成员函数_M_invoker;_M_invoker调用了接管的可调用对象;

    • 四个特化版本均继承自_Function_base::_Base_manager。

    • 其中第一个和第二个特化版本存储的可调用目标是普通函数、类实例或者Lambda表达式,两个特化版本的区别为第一个存储的可调用目标有返回值,第二个存储的可调用目标没有返回值

    • 其中第三个和第四个特化版本存储的可调用目标是类的成员函数,区别在于成员函数是否有返回值。

    • 每一个特化版本均包含一个静态函数_M_invoke,使用该函数初始化function::_M_invoker,在该函数中完成可调用目标的调用。

  • function的基类_Function_base的成员_M_functor真正接管可调用对象,当可调用对象的大小大于两个指针时存储在堆上,_M_functor指向存储位置;

    • 所以当接管的可调用对象的大小大于2个指针大小时,就会动态分配内存。否则就会直接使用_M_pod_data作为存储空间,直接存储可调用对象。
    • 普通函数指针的大小为一个指针大小,类成员函数指针的大小为2个指针,Lambda表达式、类对象的大小均有可能大于一个指针大小,甚至大于两个指针大小,取决于其成员变量的数量。
  • _Function_base的内部类_Base_manager提供接口函数。

ase的内部类_Base_manager提供接口函数。**

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

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

相关文章

系列七、Ribbon

一、Ribbon 1.1、概述 Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具,是Netflix发布的一款开源项目,其主要功能是提供客户端的软件负载均衡算法和服务调用,Ribbon客户端组件提供一系列完善的配置项,例如&#xff1a…

组合算法简单实现

组合算法 目录概述需求: 设计思路实现思路分析1.简单的字符串方式 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge …

网页爬虫对于网络安全有哪些影响?

在当今信息爆炸的时代,网络已经成为人们获取信息、交流思想和开展业务的重要平台。然而,随着网络的普及和技术的不断发展,网络安全问题也日益凸显,其中网页爬虫对网络安全的影响不容忽视。本文将就网页爬虫对网络安全的影响进行深…

XYZ世代

Z世代,Gen Zers,Generation Z ,一词最早出现于欧美地区,是美国及欧洲的流行用语,泛指在1995-2009年间出生的一代人,千禧后一代。又称网络世代、互联网世代,网生代,二次元世代&#x…

项目框架构建之3:Nuget服务器的搭建

本文是“项目框架构建”系列之3,本文介绍一下Nuget服务器的搭建,这是一项简单的工作,您或许早已会了。 1.打开vs2022创建Asp.net Web应用程序 框架选择.net framework4.8,因为nuget服务器只支持.net framework。 2.选择空项目和去…

multipath 内核接口及框架介绍

文章目录 1 云主机使用网络存储 io 流程2 multipath 介绍 1 云主机使用网络存储 io 流程 对于一个云服务环境,大致会有网络节点,存储节点,计算节点,控制节点,其中虚拟云主机在计算节点工作,而虚拟云主机&a…

Unity SVN更新提交小工具

Unity SVN更新提交小工具 前言使用说明必要前提源码参数说明 感谢 前言 Unity开发时每次都要到文件夹中操作SVN,做了一个小工具能够在Editor中直接操作。 使用说明 必要前提 前提是要安装好SVN,在文件夹右键能够看到安装的SVN 源码 using System…

UE4.27.2 网页串流

1、和Unity串流一样安装Node.js 下载地址https://nodejs.org/ 2、下载安装Epic Games启动程序https://www.unrealengine.com/zh-CN/download 3、安装UE4.7.2 4、这里就不安装像素流送演示,选个别的然后创建工程 5、启用PixelStreaming插件 6、设置额外启动参数&am…

uni-app 前后端调用实例 基于Springboot 详情页实现

锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…

OEE如何为制造企业实施ISO50001提供支持

ISO50001是一项旨在帮助企业建立和实施能源管理体系的国际标准,以提高能源效率、降低能源消耗和减少环境影响。而设备OEE(设备综合效率)作为一个关键的生产效率指标,可以为企业实施ISO50001提供重要的支持。本文将介绍ISO50001能源…

Hive10_窗口函数

窗口函数(开窗函数) 1 相关函数说明 普通的聚合函数聚合的行集是组,开窗函数聚合的行集是窗口。因此,普通的聚合函数每组(Group by)只返回一个值,而开窗函数则可为窗口中的每行都返回一个值。简单理解,就是对查询的结果多出一列…

计算机网络期末知识点总结

计算机网络概述考点 计算机网络的组成 从组成部分看:一个完整的计算机网络主要由硬件、软件、协议三大部分组成,缺一不可。硬件主要指:主机、通信链路、交换设备和通信设备等;软件主要指:用户使用的各种软件&#xf…

vue使用elementui 的 table且自定义某列表头时,添加的点击事件和自带的筛选功能有类似冒泡行为

element 自带的table 需求:在时间这一列的筛选按钮旁边添加一个批量修改按钮问题:如果不加排序这个属性,那么表格自带的筛选和新加的批量筛选点击事件会冲突(冒泡事件)解决方法:在该列添加sortable属性&…

自定义maven插件 开发步骤手册

Maven只是一套框架&#xff0c;它的功能基于全部依赖于插件来实现。因此可以通过插件开发来定制Maven。 官方文档 https://maven.apache.org/guides/plugin/guide-java-plugin-development.html 命名要求 Maven 官方的插件命名为&#xff1a;maven-<yourplugin>-plug…

Python计算圆的面积

Python 计算圆的面积 圆的面积公式为 &#xff1a; 公式中 r 为圆的半径。 # 定义一个方法来计算圆的面积 def findArea(r): PI 3.142 return PI * (r*r) # 调用方法 r float( input("请输入圆的半径:") ) print( "圆的面积为 %.3f&qu…

介绍十五种Go语言开发的IDE

当涉及到Go语言开发的IDE时&#xff0c;以下是几种常用的选择&#xff1a; Goland&#xff1a;这是由JetBrains公司开发的一款商业IDE&#xff0c;旨在为Go开发者提供符合人体工程学的开发环境。Goland整合了IntelliJ平台&#xff0c;提供了针对Go语言的编码辅助和工具集成&am…

设计模式_结构型模式_装饰器模式

装饰器模式和代理模式很像。 代理模式是已经知道代理谁了&#xff0c;所以只是对委托类的访问权限进行限制&#xff0c;因此用户只需要访问相应的代理类就可以。装饰器模式并不知道要装饰谁&#xff0c;所以需要传入具体的被装饰对象进行功能的添加 目的&#xff1a; 增加现有…

构建高效外卖配送系统:技术要点与实际代码示例

随着外卖服务需求的不断增长&#xff0c;构建一个智能化、高效的外卖配送系统成为餐饮业务成功的关键。在本文中&#xff0c;我们将重新审视外卖配送系统&#xff0c;着重思考技术架构&#xff0c;并提供一些实际代码示例&#xff0c;以展示系统中一些先进的技术要点。 技术架…

重新认识一下 vue3 应用实例

重新认识一下 vue 应用实例 &#x1f495; 创建应用实例 每个 Vue 应用都是通过 createApp 函数创建一个新的 应用实例 应用实例必须在调用了 .mount() 方法后才会渲染出来。该方法接收一个“容器”参数&#xff0c;可以是一个实际的 DOM 元素或是一个 CSS 选择器字符串 //…

Postman 安装及使用

文章目录 1. 安装 Postman1&#xff09;下载2&#xff09;安装3&#xff09;注册用户4&#xff09;登陆完成 2. 创建和发送请求1&#xff09;发送一个 GET 请求2&#xff09;发送一个 POST 请求 3. 查看响应4. 使用环境变量和变量5. 高级功能和测试6. 导出和分享请求总结 Postm…