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

C++函数对象包装器function类详解

函数对象包装器是对函数的封装,为函数对象提供一个容器,一个封装。C++中现有的可调用实体的一种类型安全的包装(相对来说,函数指针的调用不是类型安全的),换句话说,函数对象包装器就是函数的容器。

当我们有了函数的容器之后便能够更加方便的将函数、函数指针作为对象进行处理。直接调用函数包装器,传值,就可以调用函数。

函数对象包装器支持4种函数的封装

1.普通函数

2.匿名函数

3.类的成员函数

4.仿函数(重载了运算符的函数)

=========================================

1.普通函数的对象包装器

include "stdafx.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <funtional>using namespace std;int printf1(int value1,int value2)
{int ret = value1+value2;printf("普通函数的类对象包装器");printf("ret = %d",ret);return value;
}int main()
{printf1(3,5);std::function<int(int)> function1 = printf1;function1(3,6);return 0;}

===============================================================

2.匿名函数的对象包装器

Lambda的本质是一个特殊的,匿名的类类型。它是一个带有operator()的类,即仿函数。仿函数opratoer就是使一个类的使用看上去像一个函数,其实现就是类中实现一个operator(),这个类有了类似函数的行为,就是一个仿函数类了。

仿函数是一个重载了 operator() 运算符、能行使函数功能的类,这个类也称为函数对象类,这个类的对象就是函数对象。函数对象本质上是一个对象,但其使用形式看起来和函数调用一样

Lambda表达式具体形式如下:

[capture](parameters)->return-type{body}

最简单的匿名函数是[](){},它没有参数也没有返回值。在匿名函数中,[]里面用来捕获函数外部的变量,而()里面就是匿名函数的参数,{}里面就是函数的执行代码。

auto + 名字 =[]()->返回值{};
具体介绍:
1.[ ] 中括号表示函数对象的构造函数中是否接收外部变量。 [&] 表示使用引用的方式获取外部变量 [=] 表示使用值的拷贝的方式获取外部变量。2.() 这个小括号是就函数对象中的小括号符后面的参数列表。3.->返回值,需要就放,不需要就不放。根据自己需要,任君选择。4.{...} 就是函数对象的小括号运算符的函数体。

Lambda表达式实现例子

class Addnum{public:AddNum(int x):num_(num){};//int addNum(int x) const {//return num_ + x ;//}int operator(){int x} const{return num_ + x;}
}int main()
{//operatorauto add_num = AddNum(10);//auto x = add_num.addNum(5);auto x = add_num(5);std::cout<<"x:"<<x<<std::endl;//lambda//替代掉Addnum类auto add_num2 = [lamada_num =10](int x){return lamada_num +10};auto lamada_x = add_num_2(5);std::cout<<"lamada x:"<<lamada_x <<std::endl;}

========================================================

lamada函数的对象包装器

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;int printf1(int value1,int value2)
{int ret = value1+value2;printf("普通函数的类对象包装器");printf("ret = %d",ret);return value;
}class Printf_source {
public:Printf_source() {}                   //构造函数/*****************************************//operator()仿函数替代了My_Printf_source函数int My_Printf_source(int n1,int n2) {int ret = n1+n2;printf("普通函数的类对象包装器");printf("ret = %d",ret);return ret;}*********************************************///仿函数 ———————————————————代替My_Printf_source函数int operator()(int n1,int n2) {int ret = n1+n2;printf("普通函数的类对象包装器");printf("ret = %d",ret);return ret;}};int main()
{//函数对象包装器://为了函数提供了一种容器(封装),存放在对象或者变量中	printf1(3,5);          //打印出8//普通函数的封装//<int >返回值;(int)参数列表;	std::function<int(int)> function1 = printf1;function1(3,6);         //打印出9//匿名函数function<int(int)>function2 = [](int n1,int n2)->int {int ret = value1+value2;printf("类对象包装器");printf("ret = %d",ret);return ret;};function2(7,8);       //打印出15return 0;}

========================================================

再看个下面的例子,将对象包装器做为参数传递的情况

#include <iostream>
#include<functional>	//提供function模板类//传统C函数
int c_function(int a, int b)
{return a + b;
}//函数对象
class Functor
{
public:int operator()(int a, int b){return a + b;}
};//用函数指针做参数
typedef int (*pfun)(int, int);//函数的第一个参数只能接收函数指针
void show1(pfun f, int a, int b)
{std::cout << f(a, b) << std::endl;
}//用function<...>做参数
//函数第一个参数可以接收任何返回值为int,参数为int,int的可调用类型
void show2(std::function<int(int, int)> f, int a, int b)
{std::cout << f(a, b) << std::endl;
}
int main()
{show1(c_function, 3, 6);		//输出9//show1(Functor(), 3, 3);		//编译错误,因为Functor()不能转换为函数指针show2(c_function, 3, 5);		//输出8show2(Functor(), 3, 3);			//输出6system("pause");
}

==================================================

对象包装器的赋值操作

成员函数指针是一种指向类的非静态成员函数的指针。它的类型声明需要加上类名

  • 静态成员函数:取出静态成员函数的地址时,需要通过类名,但&不是必须的;
  • 非静态成员函数:取出非静态成员函数的地址时,需要通过类名,但&是必须的。非静态成员函数的第一个参数是this指针(它是隐藏的),因此在包装时需要指明第一个形参的类型为类的类型。
#include <iostream>
#include<functional>//测试用函数
int Minus(int a, int b)
{return a - b;
}//测试用类
class A
{
public:int operator()(int a, int b){return a * b;}void show(int a, int b)//普通成员函数{std::cout << a << " " << b << std::endl;}static void staticshow(int a, int b)//静态成员函数{std::cout << a << " " << b << std::endl;}
};
int main()
{using namespace std::placeholders;A a;//(1)function<>赋值类成员函数//第一种方法// 非静态成员函数包含一个隐藏的this指针,所以形参需要多定义一个类型Astd::function<void(A&, int, int)> f1(&A::show);f1(a, 3, 6);	//输出:3  6//第二种方法// 非静态成员函数包含一个隐藏的this指针,所以形参需要多定义一个类型Astd::function<int(A, int, int)> f1 = &A::show;f1(A(), 3, 6);//*********************************************************************************//(2)function<>赋值类静态成员函数//第一种方法std::function<void(int, int)> f2(&A::staticshow);f2(6, 6);//输出:6  6//第二种方法std::function<int(int,int)> f2 = A::staticshow; //*********************************************************************************//(3)function<>赋值bind//如果函数有多个参数,可以绑定部分参数,其他的参数在调用的时候指定std::function<int(int)> f3 = std::bind(Minus, 10, _1);std::cout << f3(1) << std::endl;	//输出:9//*********************************************************************************//(4)function<>赋值Lambda表达式std::function<int(int, int)> f4 = [](int a, int b) {return a + b; };std::cout << f4(3, 9) << std::endl;	//输出:12//*********************************************************************************//(5)function<>赋值函数对象//第一种方法std::function<int(int, int)> f5 = A();std::cout << f5(6, 6) << std::endl;	//输出:36//第二种方法std::function<int(int, int)> f5 = a;std::cout << f5(6, 6) << std::endl;	//输出:36system("pause");}

相关文章:

C++函数对象包装器function类详解

函数对象包装器是对函数的封装&#xff0c;为函数对象提供一个容器&#xff0c;一个封装。C中现有的可调用实体的一种类型安全的包装&#xff08;相对来说&#xff0c;函数指针的调用不是类型安全的&#xff09;&#xff0c;换句话说&#xff0c;函数对象包装器就是函数的容器。…...

SpringMVC 学习(八)之文件上传与下载

目录 1 文件上传 2 文件下载 1 文件上传 SpringMVC 对文件的上传做了很好的封装&#xff0c;提供了两种解析器。 CommonsMultipartResolver&#xff1a;兼容性较好&#xff0c;可以兼容 Servlet3.0 之前的版本&#xff0c;但是它依赖了 commons-fileupload …...

《低功耗方法学》翻译——附录A:睡眠晶体管设计

附录A&#xff1a;睡眠晶体管设计 休眠晶体管是PMOS或NMOS高VT晶体管&#xff0c;用于在待机模式下关闭设计部件的电源。PMOS休眠晶体管用于切换VDD电源&#xff0c;因此被称为“header开关”。NMOS休眠晶体管控制VSS电源&#xff0c;因此被称为“footer开关”。在90 nm及以下…...

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x

How to implement multiple file uploads based on Swagger 3.x in Spring boot 3.x Projectpom.xmlOpenAPIConfigFileUploadControllerapplication.yaml Project pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://…...

spring boot 集成科大讯飞星火认知大模型

首先到官网https://console.xfyun.cn/services/aidoc申请key 一、安装依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&…...

springboot/ssm高校宣讲会管理系统Java企业招聘宣讲系统web

演示视频&#xff1a;https://www.bilibili.com/video/BV1vz421R7cg/、 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&am…...

2024.02.23作业

1. 尝试处理普通信号 #include "test.h"#define MAXSIZE 128void handler(int signo) {if (SIGINT signo){printf("用户按下了 ctrl c 键\n");} }int main(int argc, char const *argv[]) {if (signal(SIGINT, SIG_IGN) SIG_ERR){perror("signal …...

倒模专用制作耳机壳UV树脂:改性丙烯酸树脂

倒模专用制作耳机壳的UV树脂是经过改性的丙烯酸树脂&#xff0c;具有高透明度、高粘度、快速固化的特点。这种树脂可以通过紫外线光固化&#xff0c;快速形成坚硬的表面&#xff0c;并且具有较高的硬度和耐磨性&#xff0c;因此非常适合用于制作耳机壳。 此外&#xff0c;改性丙…...

chatgpt:还有哪些人工智能和科技值得关注?

今天&#xff0c;很多人的目光都被ChatGPT吸引&#xff0c;其实&#xff0c;人工智能的范围很大&#xff0c;远不止ChatGPT或者其他自然语言的处理工具。所以说不管ChatGPT的结果如何&#xff0c;人工智能依然是未来。 那么在ChatGPT之外&#xff0c;还有没有什么值得关注的人…...

LeetCode 2997.使数组异或和等于K的最少操作次数

给你一个下标从 0 开始的整数数组 nums 和一个正整数 k 。 你可以对数组执行以下操作 任意次 &#xff1a; 选择数组里的 任意 一个元素&#xff0c;并将它的 二进制 表示 翻转 一个数位&#xff0c;翻转数位表示将 0 变成 1 或者将 1 变成 0 。 你的目标是让数组里 所有 元素…...

计算机设计大赛 深度学习大数据物流平台 python

文章目录 0 前言1 课题背景2 物流大数据平台的架构与设计3 智能车货匹配推荐算法的实现**1\. 问题陈述****2\. 算法模型**3\. 模型构建总览 **4 司机标签体系的搭建及算法****1\. 冷启动**2\. LSTM多标签模型算法 5 货运价格预测6 总结7 部分核心代码8 最后 0 前言 &#x1f5…...

WPF 附加属性+控件模板,完成自定义控件。建议观看HandyControl源码

文章目录 相关连接前言需要实现的效果附加属性添加附加属性&#xff0c;以Test修改FontSize为例依赖属性使用触发器使用直接操控 结论 控件模板&#xff0c;在HandyControl的基础上面进行修改参考HandyControl的源码控件模板原型控件模板 控件模板触发器完整样式简单使用 结论 …...

编程笔记 Golang基础 040 defer、panic 和 recover

编程笔记 Golang基础 040 defer、panic 和 recover 一、defer二、panic三、recover小结 在Go语言中&#xff0c;defer、panic 和 recover 是一组用于错误处理和控制程序流程的关键字。它们之间的交互有助于实现异常处理机制&#xff0c;并确保资源的正确释放。 一、defer defe…...

通过redfish协议实现服务器固件升级、从虚拟光驱启动自检盘并等待完成,最后截图保存

通过redfish协议实现服务器固件升级、从虚拟光驱启动自检盘并等待完成,最后截图保存 版本信息代码新开发的PCIE设备在做服务器适配时,有时需要服务器厂家更新BMC或BIOS固件。同时,我们也希望对PCIE设备做一些检测,最后收集一些信息存档。如果需要处理的服务器很多,通过BMC的界面…...

ARM 版银河麒麟桌面系统下 Qt 开发环境搭建指南

目录 前言安装Linux ARM 版 QtCreator配置 Qt Creator配置构建套件 第一个麒麟 Qt 应用程序小结 前言 在上一篇文章信创ARM架构QT应用开发环境搭建中建议大家使用 Ubuntu X86 系统作为信创 ARM 架构 QT 应用的开发环境&#xff0c;里面使用了交叉编译的方式。这对于自己的 Qt …...

架构面试题汇总:缓存(二)

目录 1. 问题&#xff1a;什么是缓存&#xff0c;以及为什么我们需要缓存&#xff1f;2. 问题&#xff1a;你能解释一下缓存击穿、缓存雪崩和缓存预热是什么吗&#xff1f;3. 问题&#xff1a;如何在Java中实现缓存&#xff1f;4. 问题&#xff1a;你如何决定哪些数据应该被缓存…...

【docker入门】1-

文章目录 参考&#xff1a; Docker – 容器虚拟化平台。 参考&#xff1a; docker入门&#xff0c;这一篇就够了。【零基础入门Docker】Dockerfile中的USER指令以及dockerfile命令详解dockerfile copy命令...

微信小程序-全局配置

个人笔记&#xff0c;仅供参考。 1.entryPagePath 代码&#xff1a; "entryPagePath": "pages/index/index" 具体用法&#xff1a; 2.pages 小程序中新增/减少页面&#xff0c;都需要对 pages 数组进行修改。 代码&#xff1a; "pages": [&…...

【Android】性能优化之内存、网络、布局、卡顿、安装包、启动速度优化

欢迎来到 Android 开发老生常谈的性能优化篇&#xff0c;本文将性能优化划分为内存、网络、布局、卡顿、安装包、启动速度七块&#xff0c;从这七块优化出发&#xff0c;阐述优化的 Application 的方式。 目录 内存优化避免内存泄漏使用内存分析工具优化数据结构和算法数据缓存…...

第3.6章:StarRocks数据导入——DataX StarRocksWriter

一、Datax 1.1 DataX 3.0概述 DataX3.0是一个异构数据源离线同步工具&#xff0c;可以方便的对各种异构数据源进行高效的数据同步。 其github地址为&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.mdhttps://github.com/alibaba/DataX/blob/mast…...

【非递归版】归并排序算法(2)

目录 MergeSortNonR归并排序 非递归&归并排序VS快速排序 整体思想 图解分析​ 代码实现 时间复杂度 归并排序在硬盘上的应用&#xff08;外排序&#xff09; MergeSortNonR归并排序 前面的快速排序的非递归实现&#xff0c;我们借助栈实现。这里我们能否也借助栈去…...

[C++]C++实现本地TCP通讯的示例代码

这篇文章主要为大家详细介绍了C如何利用TCP技术,实现本地ROS1和ROS2的通讯,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下 概要服务端代码 头文件源代码客户端代码 概要 利用TCP技术&#xff0c;实现本地ROS1和ROS2的通讯。 服务端代码 头文件 #include &…...

Sora - 探索AI视频模型的无限可能

文章目录 每日一句正能量前言技术解析应用场景未来展望伦理与创意用户体验与互动后记 每日一句正能量 . 一个人&#xff0c;如果没有经受过投资失败的痛楚&#xff0c;又怎么会看到绝望之后的海阔天空。很多时候&#xff0c;经历了人生中最艰难的事&#xff0c;反而锻造了最坚强…...

【JavaScript 漫游】【022】事件模型

文章简介 本篇文章为【JavaScript 漫游】专栏的第 022 篇文章&#xff0c;对 JavaScript 中事件模型相关的知识点进行了总结。 监听函数 浏览器的事件模型&#xff0c;就是通过监听函数&#xff08;listener&#xff09;对事件做出反应。事件发生后&#xff0c;浏览器监听到…...

【加密算法】RSA非对称加密算法简介

目录 前言 工作原理 密钥生成 加密和解密 在Java中使用RSA 生成密钥对 加密和解密数据 加密数据 解密数据 注意事项和最佳实践 结论 前言 RSA&#xff08;Rivest-Shamir-Adleman&#xff09;是一种基于数论的非对称加密算法&#xff0c;广泛应用于数字签名、数据加密…...

深入理解 JavaScript 对象原型,解密原型链之谜(上)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…...

产品经理学习-产品运营《什么是SOP》

目录 什么是SOP 如何执行SOP 执行SOP的重点 什么是SOP SOP就是项目流程操作的说明书 日常工作中的例行操作&#xff1a; 例行操作是指&#xff0c;在每一天&#xff0c;针对每一个用户&#xff0c;在每个项目之中&#xff0c;都必须完成的操作&#xff0c;这些必须完成的操…...

大数据Hadoop生态圈

存储&#xff1a; HDFS(namenode,datanode) 计算&#xff1a;MapReduce(mapreduce&#xff0c;基于磁盘) 便于用sql操作&#xff1a;Hive(核心 metastore&#xff0c;存储这些结构化的数据)&#xff0c;同类的还有Impala&#xff0c;hbase等 基于yaml的资源调度 hive &…...

算法简介:查找与算法运行时间

文章目录 1. 二分查找与简单查找1.1 运行时间 2. 旅行商问题 算法是一组完成任务的指令。任何代码片段都可以视为算法。 1. 二分查找与简单查找 二分查找是一种算法&#xff0c;其输入是一个有序的元素列表&#xff0c;如果要查找的元素包含在列表中&#xff0c;二分查找返回…...

零基础C++开发上位机--基于QT5.15的串口助手(三)

本系列教程本着实践的目的&#xff0c;争取每一节课都带大家做一个小项目&#xff0c;让大家多实践多试验&#xff0c;这样才能知道自己学会与否。 接下来我们这节课&#xff0c;主要学习一下QT的串口编程。做一款自己的串口助手&#xff0c;那么这里默认大家都是具备串口通信…...

一个在线做笔记的网站/百度如何做广告

一、操作系统提代一个开发接口给硬件开发商&#xff0c;让他们可以根据这个接口设计可以驱动他们硬件的驱动程序。二、应用程序是参考操作系统提供开发接口所开发出来的软件三、核心功能&#xff1a;系统呼叫接口、程序管理、内存管理、文件系统管理、装置驱动四、CPU每次能够处…...

做网站费用怎么入账/猪八戒网接单平台

用户名&#xff1a;tianfang 电子邮件&#xff1a;quart163.com 注册码&#xff1a;2NnUqd3shO2agta0xNjcusfK1LXO 给出一个C-Free 5.0中文专业版的下载地址&#xff1a;http://www.programarts.com/cfree_ch/download.htm。...

网站建设经营范围/公众号排名优化软件

PropertyDescriptor类&#xff1a; PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法&#xff1a;   1. getReadMethod()&#xff0c;获得用于读取属性值的方法   2. getWriteMethod()&#xff0c;获得用于写入属性值的方法 注&#xff1a;…...

土木工程毕业设计网站/百度云登录入口

bin目录 该目录用于存放一些可执行程序 &#xff0c;如 javac.exe java编译器 java.exe java运行工具 jar.exe 打包工具 javadoc.exe 文档生成工具 db目录 db目录是一个小型的数据库 从jdk6.0开始&#xff0c;java中引用了一个新的成员JavaDB,这是一个线java实现、开源的数…...

网上发布信息的网站怎么做的/百度极速版app下载安装挣钱

点击上方“蓝色字”可关注我们&#xff01;编辑&#xff1a;铅笔盒Po.et 核心组件概述本文由Po.et核心开发成员Lautaro Dragan 撰写&#xff0c;详细剖析了Po.et的技术细节。在Po.et发布时&#xff0c;我们就有打算要建立一个可以用来管理数字资产所有权的安全、稳定的系统的愿…...

申报湖南创新型省份建设专项网站/提高网站收录的方法

1.类加载器 Java虚拟机中可以安装多个类加载器&#xff0c;系统默认主要三个类加载器&#xff0c;每个类负责加载特定位置的类&#xff1a;BootStrap&#xff08;内嵌在java虚拟机中由C编写&#xff09;&#xff0c;ExtClassLoader&#xff0c;AppClassLoader。当然也可以自定义…...