C++11第四弹:包装器

news2024/12/24 21:27:19

在这里插入图片描述

🌈个人主页: 南桥几晴秋
🌈C++专栏: 南桥谈C++
🌈C语言专栏: C语言学习系列
🌈Linux学习专栏: 南桥谈Linux
🌈数据结构学习专栏: 数据结构杂谈
🌈数据库学习专栏: 南桥谈MySQL
🌈Qt学习专栏: 南桥谈Qt
🌈菜鸡代码练习: 练习随想记录
🌈git学习: 南桥谈Git

🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈
本科在读菜鸡一枚,指出问题及时改正

文章目录

  • 包装器
    • function包装器
      • 应用场景
      • 包装成员函数指针
    • bind
      • 调整参数顺序
      • 调整参数个数

包装器

包装器是一个类模板

C++中的可调用对象:函数指针(类型定义很复杂)、仿函数对象(定义一个类的时候,用的时候有些麻烦,其次不适合统一类型)、lambda(没有类型概念)、包装器

function包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。

std::function在头文件<functional>
类模板原型:

template <class T> function; // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;

模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参
在这里插入图片描述

他不是用来定义可调用对象,是用来包装可调用对象:
在这里插入图片描述

#include<functional>

int f(int a, int b)
{
	return a + b;
}

struct Functor
{
public:
	int operator() (int a, int b)
	{
		return a + b;
	}
};

int main()
{
	function<int(int, int)> fc1;
	//包装函数指针
	function<int(int, int)> fc2 = f;
	cout << fc2(1, 2) << endl;
	//包装仿函数
	function<int(int, int)> fc3 = Functor();
	cout << fc3(2, 3) << endl;
	//包装lambda表达式
	function<int(int, int)> fc4 = [](int x, int y) {return x + y; };
	cout << fc4(3, 4) << endl;

	return 0;
}

在这里插入图片描述

应用场景

力扣:150.逆波兰表达式求值

class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> st;

        //命令和对应的函数动作结合
        map<string,function<int(int,int)>> opfuncMap={
            {"+",[](int a,int b){return a+b;}},
            {"-",[](int a,int b){return a-b;}},
            {"*",[](int a,int b){return a*b;}},
            {"/",[](int a,int b){return a/b;}}
        };

        for(auto& str:tokens)
        {
            if(opfuncMap.count(str)) // 是操作符
            {
                function<int(int,int)> func=opfuncMap[str];
                int right=st.top();
                st.pop();
                int left=st.top();
                st.pop();
                st.push(func(left,right));
                
            }
            else //是操作数 
            {
                st.push(stoi(str));
            }
        }
        return st.top();
    }
};

在这里插入图片描述

包装成员函数指针

在包装静态成员指针函数时,当我们需要用到某个函数时,需要在前面指定类域。但如果不是静态时,不仅需要添加类域,还需要添加一个&

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}
	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	function<int(int, int)> fc1 = Plus::plusi;
	cout << fc1(1, 2) << endl;

	function<double(Plus*, double, double)> fc2 = &Plus::plusd;
	Plus plus;
	cout << fc2(&plus, 1.1, 2.2) << endl;
	
	function<double(Plus, double, double)> fc3 = &Plus::plusd;
	//Plus plus;
	cout << fc3(Plus(), 1.1, 2.2) << endl;

	return 0;
}

fc1 是一个 std::function<int(int, int)> 对象,绑定到静态成员函数 Plus::plusi。调用 fc1(1, 2) 输出 3

fc2 是一个 std::function<double(Plus*, double, double)> 对象,绑定到非静态成员函数 Plus::plusd。它接受一个 Plus* 指针和两个 double 类型的参数。调用 fc2(&plus, 1.1, 2.2) 计算 1.1 + 2.2 并输出 3.3

bind

std::bind函数定义在头文件中,是一个函数模板,它就像一个函数包装器(适配器),接受一个可调用对象(callable object),生成一个新的可调用对象来“适应”原对象的参数列表。一般而言,我们用它可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M可以大于N,但这么做没什么意义)参数的新函数。同时,使用std::bind函数还可以实现参数顺序调整等操作。

原型:

template <class Fn, class... Args>
bind (Fn&& fn, Args&&... args);
with return type (2)	
template <class Ret, class Fn, class... Args>
bind (Fn&& fn, Args&&... args);

可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

调用bind的一般形式:auto newCallable = bind(callable,arg_list);

调整参数顺序

int Sub(int a, int b)
{
	return a - b;
}

int main()
{
	auto f1 = Sub;
	cout << f1(10, 5) << endl;

	auto f2 = bind(Sub, placeholders::_2, placeholders::_1);
	cout << f2(10, 5) << endl;

	return 0;
}

在这里插入图片描述
在这里插入图片描述

调整参数个数

class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};

int main()
{
	Sub sub;
	auto f3 = bind(&Sub::sub, Sub(), placeholders::_2, placeholders::_1);
	cout << f3(10, 5) << endl;

	return 0;
}

参数顺序:bind(&Sub::sub, &s, _2, _1) 绑定了成员函数 sub s 对象,并指定 _2_1 的位置。调用 f3(10, 5) 会将 5 映射到 _210 映射到 _1,因此 f3(10, 5) 实际上会调用 s.sub(5, 10),结果是 5 - 10,即 -5

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索UWB技术的独特优势:实现高精度定位

UWB定位技术是一种利用无线信号进行精确位置定位的技术&#xff0c;它利用超宽带无线电信号通过测量信号的到达时间、相位差和信号能量等参数来确定物体的精确位置。 UWB定位技术具有多种优势&#xff0c;首先&#xff0c;它具有较高的定位精度&#xff0c;可实现毫米级的精确…

如何防止ZIP压缩文件被随意打开?

ZIP文件是常见的压缩文件格式&#xff0c;为了保护压缩包不被随意打开&#xff0c;很多人还会给ZIP压缩包设置密码&#xff0c;用于保护文件的数据安全&#xff0c;以下是一篇关于如何防止ZIP压缩文件被随意打开的详细探讨。 引言 ZIP文件因其高效的压缩率和广泛的兼容性&…

目标检测中的解耦和耦合、anchor-free和anchor-base

解耦和耦合 写在前面 在目标检测中&#xff0c;objectness&#xff08;或 objectness score&#xff09;指的是一个评分&#xff0c;用来表示某个预测框&#xff08;bounding box&#xff09;中是否包含一个目标物体。 具体来说&#xff0c;YOLO等目标检测算法需要在每个候选区…

基于OpenSSL的密码管理系统-应用密码学课程报告

第1章 概要设计 1.1 设计目的 本研究旨在设计并实现一个基于OpenSSL的密码管理系统&#xff0c;该系统具备密钥对的生成、密钥上传、密钥的核对、身份认证、文件与邮件的加密和解密、数字签名及数字证书管理等常用功能。研究的意义主要体现在以下几个方面&#xff1a; 提升网…

Ubuntu20-xrdp与Windows-mstsc远程桌面连接

ubuntu端 sudo adduser yu //输入密码和确认密码&#xff0c;后面一路回车&#xff0c;新建用户yu&#xff0c;确保用户没有被登录 sudo apt install xrdp //安装xrdp sudo systemctl status xrdp //查看xrdp服务状态 sudo adduser xrdp ssl-cert //将用户 xrdp 添加到 ss…

悟空crm客户管理系统二次开发 单独新增表格字段

1&#xff0c;仪表盘&#xff08;数据来源修改&#xff09; 注意点&#xff1a;有层级关系&#xff0c;管理员账号可以看到全部数据&#xff0c;主管只能看到下属数据。 2、在客户管理菜单里面 增加一个时间筛选、额度汇总 /*** 获取客户列表** param $type* param $content*…

在线API文档,技术文档工具源码ShowDoc

ShowDoc是一个非常适合IT团队的在线API文档、技术文档工具。通过showdoc&#xff0c;你可以方便地使用markdown语法来书写出美观的API文档、数据字典文档、技术文档、在线excel文档等等。 代码下载

单机docker-compose部署minio

单机多副本docker-compose部署minio 简单介绍 如果服务器有限可以单机挂载多硬盘实现多副本容错&#xff08;生产不推荐&#xff09; 部署好的文件状态 有两个重要文件 docker-compose.yaml和nginx.conf docker-compose.yaml是docker部署容器的配置信息包括4个minio和1个ng…

云微客全流程闭环,实现在短视频营销中快速拿结果

不知道大家有没有在抖音或者是其他短视频平台见过这样的视频&#xff0c;这一类的视频制作的非常简单&#xff0c;只有一个简单的文字搭配上背景素材&#xff0c;但是它的播放量和互动量却是惊人的好。在短视频领域的朋友想必有过这样心声&#xff0c;这么好的播放量&#xff0…

USB虚拟串口——CDC ACM 虚拟串口(不使用 IAD)

文章目录 CDC ACM 虚拟串口实现描述符结构设备描述符配置描述符集合配置描述符接口 1 的描述符接口描述符类特殊描述符输入端点描述符接口 2 的描述符接口描述符输出端点描述符输入端点描述符类特殊请求set control line statusget line codingset line codingCDC 数据交互主机…

【数据结构】之排序

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1 排序1.1 排序的概念1.2 几种常见的排序算法&#xff1a; 2 常见排序算法的实现2.1 插入排序2.…

Java项目: 基于SpringBoot+mybatis+maven美发门店管理系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven美发门店管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简…

Java在零工市场中的应用:构建灵活高效的劳动力平台

随着数字经济的迅猛发展&#xff0c;零工经济作为一种新兴的劳动力市场模式&#xff0c;正在全球范围内迅速崛起。零工市场通过互联网平台将服务提供者与需求者进行快速匹配&#xff0c;使得个人可以临时、自由地提供服务&#xff0c;企业则能够按需雇佣劳动力&#xff0c;实现…

总算学到路由了————vue3中路由介绍

基本创建步骤 下载vue-router的依赖&#xff1a;npm install vue-router4 创建好路由组件&#xff0c;放在pages/views里面 &#xff08;views 文件夹通常包含应用的页面。这些页面通常是与路由相对应的组件&#xff0c;代表应用的不同视图&#xff0c;components 文件夹通…

基于yolov8的行人过马路危险行为检测告警系统python源码+onnx模型+精美GUI界面

【算法介绍】 基于YOLOv8的行人过马路危险行为检测告警系统是一种高效、精准的智能交通监控解决方案。该系统利用YOLOv8这一前沿的目标检测算法&#xff0c;能够快速识别图像或视频中的行人&#xff0c;并准确判断其是否存在过马路时的危险行为&#xff0c;如玩手机、打电话等…

MySQL 查询数据库的数据总量

需求&#xff1a;查看MySQL数据库的数据总量&#xff0c;以MB为单位展示数据库占用的磁盘空间 实践&#xff1a; 登录到MySQL数据库服务器。 选择你想要查看数据总量的数据库&#xff1a; USE shield;运行查询以获取数据库的总大小&#xff1a; SELECT table_schema AS Datab…

抖音视频下载

对于特别喜欢的视频有时需要珍藏&#xff0c;下文方法可能会帮到你&#xff0c;但要注意尊重版权和遵守相关声明。 Edge浏览器打开抖音短视频&#xff0c;按F12&#xff0c;选择 网络&#xff1b;筛选条件?a&#xff1b;双击搜索结果打开视频&#xff1b;选择想要的视频&…

SpringBoot框架下的房产销售系统开发

第一章 绪 论 1.1背景及意义 房产销售也都将通过计算机进行整体智能化操作&#xff0c;对于房产销售系统所牵扯的管理及数据保存都是非常多的&#xff0c;例如管理员&#xff1b;首页、个人中心、用户管理、销售经理管理、房源信息管理、房源类型管理、房子户型管理、交易订单管…

aspcms webshell漏洞复现

1.【ip】/admin_aspcms/login.asp访问后台&#xff0c;admin 123456 登录 2.点击【扩展功能】【幻灯片设置】点击【保存】开启代理进行抓包 3.在抓取的数据包中修改 slideTextStatus 字段的值为以下代码并进行发包 访问影响文件 字段值 1%25><%25Eval(Request (chr(65))…

FastAPI 中的错误处理:如何让错误信息更有价值

开头&#xff1a; 下面详细介绍如何在 FastAPI 中实现有效的错误处理策略。我们将讨论使用 HTTPException 来抛出带有详细描述的错误&#xff0c;定义 Pydantic 模型来结构化错误响应&#xff0c;以及如何通过自定义异常处理器来统一处理错误。此外&#xff0c;我们还将展示如…