C++-第十七章:包装器
目录
第一节:std::function
第二节:std::bind
2-1.基本介绍
2-2.调整顺序(不常用)
2-3.调整个数
2-4.std::bind与std::function
下期预告:
C++中有3种可调用对象:函数指针、仿函数对象、lambda函数,经过包装器包装后屏蔽了底层细节,就可以用更加通用的方式使用3种可调用函数了。
第一节:std::function
std::function的底层实现其实是仿函数对象,通过嵌套一层对象,实现了3种可调用对象在类型上的统一(都变成了对象)。
std::function包含在头文件<functional>中,它的使用方法如下:
std::function<返回类型(参数类型)> 名字 = 可调用对象;#include <functional>// 包装函数指针 int Add(int a,int b) {return a + b; } std::function<int(int, int)> f1 = Add;// 包装仿函数 class Func { public:int operator()(int a, int b){return a + b;} }; std::function<int(int, int)> f2 = Func();// 包装lambda函数 std::function<int(int, int)> f3 = [](int a, int b) {return a + b; };int main() {std::cout << f1(1, 2) << std::endl;std::cout << f2(1, 2) << std::endl;std::cout << f3(1, 2) << std::endl;return 0; }
![]()
如果封装的是类中的非静态成员函数,参数记得加上隐含的this指针类型,而且只有公有函数才能被封装:
class Person { public:void print(){std::cout << "我被调用了!" << std::endl;} }; std::function<void(Person*)> f = &Person::print; // 这个&必不可少调用时也要传入一个对象的指针:
int main() {Person LiHua;f(&LiHua); // 等价于 LiHua.print();return 0; }
若包装时使用Person作为参数,而不是指针,就可以直接传入对象进行调用:
#include <functional> class Person { public:void print(){std::cout << "我被调用了!" << std::endl;} }; std::function<void(Person)> f = &Person::print; // 这个&必不可少 int main() {Person p;f(p);return 0; }
它们本质上都是使用对象调用成员函数。
如果是类中的公有静态函数,则不需要隐含的this指针类型:
#include <functional> class Person { public:static void print(){std::cout << "我被调用了!" << std::endl;} }; std::function<void()> f = &Person::print; // 这个&可以省略 int main() {f(); // 等价于 LiHua.print();return 0; }
第二节:std::bind
使用bind可以调整函数参数的传入顺序和个数。
2-1.基本介绍
std::bind的原型如下:
template<class Fn,class ...Args> bind(Fn&& fn,Args&&... args);template<class Ret,class Fn,class ...Args> bind(Fn&& fn,Args&&... args);模版参数包就包含了可调用对象的所有参数类型。
std::bind的使用格式如下:
std::bind(可调用对象,占位符1,占位符2,...);占位符有多个,而且占位符与参数是一一对应的,占位符1表示第一个参数,占位符2表示第二个参数。
2-2.调整顺序(不常用)
因为占位符1表示第一个参数,占位符2表示第二个参数,只要把占位符1放在后面,那么第一个参数就需要在后面传入了:
#include <functional> void func(int a, float b, std::string c) {std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl; } int main() {auto f = std::bind(&func,std::placeholders::_3, std::placeholders::_2, std::placeholders::_1);return 0; }像这样,它的占位符顺序是3、2、1,而不是正常的1、2、3。那么使用 f 时参数类型应该先传入std::string,再传入float,最后传入int:
f("Hello", 0.2, 12);
只是顺序改变了,对原函数的逻辑没有影响。
2-3.调整个数
调整个数不是真正的减少参数个数,实际上是指定某个或者某些参数的值,调用时这些参数就赋值为指定的值。
指定后,剩下的参数再重新分占位符1、2、3:
#include <functional> void func(int a, float b, std::string c) {std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl; } int main() {// 指定第一个参数的值为12auto f = std::bind(&func,12, std::placeholders::_1, std::placeholders::_2);// 第一个参数已经预先传好了,只传剩下两个参数f(0.2,"Hello");return 0; }
这种用法的主要场景是在类中进行函数传参时,如果一个函数类型的参数只接收3个参数的可调用对象,而对象中的非静态函数有3个显式的参数+1个this指针,并且这个函数因为需要用到对象的数据而不能设置为静态,也不能减少参数。这时候将 this 作为指定为 this指针 的值,它就变成只用传入3个参数的可调用对象了。
例如:
它的第一个参数就被指定为 this。
2-4.std::bind与std::function
可调用对象被std::bind包装过后也是可调用对象,所以可以将std::bind后的可调用对象传给std::function管理起来:
#include <functional> void func(int a, float b, std::string c) {std::cout << a << std::endl;std::cout << b << std::endl;std::cout << c << std::endl; } int main() {// 如果指定了值,那么<>中的参数也省略被指定的类型 std::function<void(float,std::string)> f = std::bind(&func, 12, std::placeholders::_1, std::placeholders::_2);// 第一个参数已经预先传好了,只传剩下两个参数f(0.2,"Hello");return 0; }
下期预告:
下一章将讲述C++11的线程库,包括线程的管理、锁。
相关文章:
C++-第十七章:包装器
目录 第一节:std::function 第二节:std::bind 2-1.基本介绍 2-2.调整顺序(不常用) 2-3.调整个数 2-4.std::bind与std::function 下期预告: C中有3种可调用对象:函数指针、仿函数对象、lambda函数,经过包装器包装后屏…...
如何判断邮件列表中邮箱地址的有效性?
判断邮件列表中邮箱地址的有效性,对于提高邮件送达率、避免资源浪费和维护发件人信誉至关重要。以下是一些实用的判断方法: 一、使用专业的邮箱验证工具 市面上有许多专业的邮箱验证工具,如 Geeksend邮箱验证工具 等。这些工具通过与邮件服…...
翻译: 深入分析LLMs like ChatGPT 二
监督微调(SFT) 使用人工标注的对话数据集(如1M条"用户-助手"对话)继续训练模型。 标注员遵循指导原则编写理想回答,使模型学习助手的回应风格。 示例对话格式: [系统] 你是一个有帮助的AI助手……...
conda怎么迁移之前下载的环境包,把python从3.9升级到3.10
克隆旧环境(保留旧环境作为备份) conda create -n cloned_env --clone old_env 在克隆环境中直接升级 Python conda activate cloned_env conda install python3.10 升级 Python 后出现 所有包导入失败 的问题,通常是因为依赖包与新 Pyth…...
k8s之pod的调度之污点与容忍污点,什么是污点? 如何容忍污点
在 Kubernetes 中,污点(Taint) 和 容忍(Toleration) 是用于控制 Pod 调度到特定节点的重要机制。污点允许节点拒绝某些 Pod 的调度,而容忍则允许 Pod 忽略节点的污点,从而调度到特定节点上。 1.…...
Linux切换Python版本
1、更新apt sudo apt update2、查询python安装路径 which python 或者which python33、查询安装版本 # 查看所有以 "python" 开头的命令(包括版本号) ls -l 安装路径* 例如 ls -l /usr/bin/python*4、修改软连接 udo unlink /usr/bin/pyt…...
TCP的三次握手与四次挥手:建立与终止连接的关键步骤
引言 TCP(传输控制协议)工作在OSI模型的传输层。OSI模型将计算机网络功能划分为七个层级,从底层到顶层依次是:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。传输层负责在网络节点之间提供可靠的端到端通信&a…...
2025计算机考研复试资料(附:网课+历年复试真题+140所高校真题+机试)
目录 2025 计算机考研复试经验全攻略,附超全资源🎁 (一)网课资源 (二)历年复试真题 (三)140 所高校真题 二、专业知识复习篇 (一)复试专业课程 二&…...
Milvus高性能向量数据库与大模型结合
Milvus | 高性能向量数据库,为规模而构建Milvus 是一个为 GenAI 应用构建的开源向量数据库。使用 pip 安装,执行高速搜索,并扩展到数十亿个向量。https://milvus.io/zh Milvus 是什么? Milvus 是一种高性能、高扩展性的向量数据…...
【Groovy】流程控制
1 选择结构 Groovy 中选择结构主要包含 if -else、switch 语句,并且可以返回结果。 1.1 if-else def score 85 if (score > 90) {println("优秀") } else if (score > 80) {println("良好") } else if (score > 60) {println("…...
腾讯游戏完成架构调整 IEG新设五大产品事业部
易采游戏网2月28日独家消息:继1月份腾讯天美工作室群完成内部组织架构调整后,腾讯旗下互动娱乐事业群(IEG)再次宣布对组织架构进行优化调整。此次调整的核心在于新设立了五大产品事业部,包括体育产品部、音舞产品部、V…...
达梦数据库系列之安装及Mysql数据迁移
达梦数据库系列之安装及Mysql数据迁移 1. 达梦数据库1.1 简介1.2 Docker安装达梦1.2.1 默认密码查询1.2.2 docker启动指定密码 1.3 达梦数据库连接工具1.3.1 快捷键 2 Mysql数据库迁移至达梦2.1 使用SQLark进行数据迁移 1. 达梦数据库 1.1 简介 DM8是达梦公司在总结DM系列产品…...
什么是 MGX:MetaGPT
什么是 MGX:MetaGPT MetaGPT是由思码逸(OpenDILab)团队开发的一款专注于生成式AI驱动的软件开发框架,MGX可能是其衍生或升级的相关成果,它创新性地将大语言模型引入软件开发流程,模拟人类软件团队的协作方式,能让用户通过自然语言描述需求,即可自动生成完整的软件项目,…...
java jar包内的jar包如何打补丁
问题描述: 主包:hisca.jar,解压后 BOOT-INFO/lib下有其他jar包 因为一个小bug,需要修改这个hisca包下BOOT-INF/lib下的子jar包service-hisca-impl-1.0.0.jar中的一个service类及xml文件 操作步骤: 1、主包jar -xvf …...
一个借助ai分析市场交易数据的流程方法
回答和代码借助 AI 生成,仅供参考,不构成任何专业建议。 如有投资损失请自负盈亏。 一个提取比特币的不同周期数据,并进行文本的初步分析的程序。 用途:把文本提供给ai,进行深度思考,从而达到一个相对比较…...
安装electron 提示RequestError: certificate has expired
最近需要开发electron,遇到了一个生产问题,使用了很多办法都不生效。 现在记录下具体情况 一执行 yarn add electron 就开始报错 [2/4] 🚚 Fetching packages... [3/4] 🔗 Linking dependencies... [4/4] 🔨 B…...
Flutter状态管理框架GetX最新版详解与实践指南
一、GetX框架概述 GetX是Flutter生态中轻量级、高性能的全能开发框架,集成了状态管理、路由导航、依赖注入等核心功能,同时提供国际化、主题切换等实用工具。其优势在于代码简洁性(减少模板代码约70%)和高性能(基于观…...
详细对比所有开源许可及其不同版本
qwen 以下是基于知识库内容对常见开源许可证及其不同版本的详细对比,重点突出版本间差异和核心条款变化: 1. GPL(GNU General Public License) 版本: v2 vs v3 GPLv2(1991): 要求衍生代码开源,…...
【企业场景】上线的项目如何进行限流
一、常见的四种速率限流算法 对于限流,最为直接的就是速率限流了 固定窗口算法 比如 10r/s 就是把时间线分为 1s 一段,也就是周期为 1s,对一个时间段的请求进行计数,超过 10 则舍弃,未超过则直接处理经过 1s 后&…...
git - study
文章目录 git - study概述可以用 git gui工具来添加快捷命令工具如果要在提交日志中搜索,可以用gitk的view编辑功能实验环境直接用git自带环境进行git操作的好处查看git所有配置配置全局数据配置项目专用的数据查询配置数据的原始值配置git使用的文本编辑器获取某个…...
编写一个程序,输出1到100的所有质数(Python版)
编写一个程序,输出1到100的所有质数 以下是一个用 Python 编写的程序,用于输出 1 到 100 的所有质数: def is_prime(n):# 检查 n 是否为质数if n < 1: # 如果 n 小于等于 1,则不是质数return False# 遍历从 2 到 n 的平方根的…...
wifi5和wifi6,WiFi 2.4G、5G,五类网线和六类网线,4G和5G的区别
wifi5和wifi6的区别 是Wi-Fi 5和Wi-Fi 6的选择与路由器密切相关。路由器是创建和管理无线网络的设备,它决定了网络的类型和性能。具体来说: 路由器的标准支持:路由器可以支持不同的Wi-Fi标准,如Wi-Fi 5(802.11ac)和Wi-Fi 6(802.11ax)。支持Wi-Fi 6的路由器能够提供更高…...
FPGA之硬件设计笔记-持续更新中
目录 1、说在前面2、FPGA硬件设计总计说明3、 原理图详解 - ARITX - 7 系列3.1 顶层框图介绍3.2 FPGA 电源sheet介绍:3.2.1 bank 14 和 bank 15的供电3.2.2 bank 0的供电3.2.3 Bank34 35 的供电 3.3 核电压和RAM电压以及辅助电压 4 原理图详解-- Ultrascale ARTIX4.…...
Python--内置模块和开发规范(上)
1. 内置模块 1.1 JSON 模块 核心功能 序列化:Python 数据类型 → JSON 字符串 import json data [{"id": 1, "name": "武沛齐"}, {"id": 2, "name": "Alex"}] json_str json.dumps(data, ensure_a…...
步步为营:用 torch.arange 快速生成数字序列
前言 在 PyTorch 中,torch.arange 就像一个神奇的小精灵,悄然无声地帮助你生成一系列数值,简直是深度学习模型的“数字魔法师”。你只需简单的几个参数,它就能为你呈现完美的数值序列,从而让数据准备工作变得轻松愉快。你可能会问,这个小精灵到底是怎么做到的?它怎么能…...
使用Spring Data Redis操作Redis
使用Spring Data Redis操作Redis 文章目录 使用Spring Data Redis操作Redis1. 添加依赖2. 配置Redis连接3. 创建Redis配置类4. 编写Redis操作类5. 操作各种数据类型操作字符串(String)操作列表(List)操作集合(Set&…...
嵌入式开发:傅里叶变换(5):STM32和Matlab联调验证FFT
目录 1. MATLAB获取 STM32 的原始数据 2. 将数据上传到电脑 3. MATLAB 接收数据并验证 STM32进行傅里叶代码 结果分析 STM32 和 MATLAB 联调是嵌入式开发中常见的工作流程,通常目的是将 STM32 采集的数据或控制信号传输到 MATLAB 中进行实时处理、分析和可视化…...
【无人机三维路径规划】基于豪猪算法CPO、蜣螂算法DBO、人工兔ARO实现复杂山地模型下无人机路径规划附Matlab代码
无人机三维路径规划 一、引言 1.1、研究背景与意义 无人机技术在近年来得到了快速发展,其在军事侦察、民用测绘、物流配送和灾难救援等领域的应用日益广泛。路径规划作为无人机技术中的核心问题之一,直接影响到无人机的飞行效率和安全性。在复杂多变的…...
Cursor AI编程-详细教程
一点准备工作 Cursor方法论:简单到没有方法 Cursor能做什么 Cursor官网:https://www.cursor.com/ja Cursor文档:Cursor – Welcome to Cursor Cursor论坛:Weekly - Cursor - Community Forum 写程序代码 举例: 设…...
AI关于SHAP分析与列线图(算法)解释线性模型矛盾之处的解释
AI关于SHAP分析与列线图(算法)解释线性模型矛盾之处的解释 两种解释方法在个案的局部解释方面,有矛盾之处,其背后的原理已经超出了我的知识范畴,以下是询问AI的几个问题,希望能从中梳理出一个合理的解释。…...



