在这里插入图片描述
各位大佬好,我是落羽!一个坚持不断学习进步的学生。
如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步!

也欢迎关注我的blog主页: 落羽的落羽

文章目录

  • 一、function
    • 1. 概念
    • 2. 用法
  • 二、bind
    • 1. 概念
    • 2. 用法

一、function

1. 概念

上一篇文章我们学习了lambda表达式的用法。

std::function是 C++11 标准库在 <functional> 头文件中引入的一个通用、多态的函数包装器。它的本质是一个类模板,可以包装、存储、复制和调用任何可调用对象(函数指针、仿函数、lambda表达式、bind表达式等),存储的可调用对象被称为function的目标。function不含目标则为空,调用空function的目标会抛异常。
函数指针、仿函数、lambda表达式等可调用对象的类型各不相同,function可以统一类型,对他们进行包装,这样在很多地方就方便声明可调用对象的类型。

2. 用法

在这里插入图片描述
以上是function的原型,使用语法为:

#include <functional>
std::function<返回类型(参数类型1, 参数类型2, ...)> 包装器名称;

来看一段代码实例:

#include <iostream>
#include <functional>
using namespace std;// 普通函数
int add(int a, int b) 
{return a + b;
}// Lambda表达式
auto multiply = [](int a, int b) { return a * b; };// 仿函数
struct Subtract 
{int operator()(int a, int b) const {return a - b;}
};int main() 
{// 声明一个function,他可以包装一个返回int,接受两个int参数的可调用对象function<int(int, int)> func;// 包装普通函数func = add;cout << "Add: " << func(10, 5) << endl; // 输出 15// 包装 Lambda 表达式func = multiply;cout << "Multiply: " << func(10, 5) << endl; // 输出 50// 包装仿函数对象Subtract sub;func = sub;cout << "Subtract: " << func(10, 5) << endl; // 输出 5// 甚至可以包装一个临时的Lambdafunc = [](int a, int b) { return a / b; };cout << "Divide: " << func(10, 5) <<std::endl; // 输出 2return 0;
}

有一个特殊的点是,类的成员函数也可以被包装,但成员函数必须要指定类域并且前面加上&才能获取地址,静态成员函数可以不加&,但是为了方便记忆,建议成员函数都加上吧。这时还有一个问题,普通成员函数还有一个隐含的this指针,在类外包装时,也一定要显式写出this指针参数类型,即当前类的指针类型:

class Plus
{
public:Plus(int n = 10):_n(n){}static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return (a + b) * _n;}private:int _n;
};int main()
{function<int(int, int)> f = &Plus::plusi;cout << f(1, 1) << endl; // 输出2function<double(Plus*, double, double)> f1 = &Plus::plusd;//调用时实例化出一个对象取地址传参即可,或者传对象也可以Plus pdcout << f1(&pd, 1.1, 1.1) << endl; // 输出22/*function<double(Plus, double, double)> f1 = &Plus::plusd;Plus pdcout << f1(pd, 1.1, 1.1) << endl; */return 0;
}

二、bind

1. 概念

std::bind是一个函数模板,也包含在<functional>中,是一个可调用对象的包装器,可以把他看做一个函数适配器,对接收的可调用对象处理后返回一个可调用对象。bind可以用来调整参数个数和参数顺序。
在这里插入图片描述

2. 用法

调用bind的一般形式为:auto newCallable = bind(callable, arg_list);其中newCallable本身是一个可调用对象,arg_list是一个用逗号分隔的参数列表,对应给定callable的参数。arg_list中的参数可能包含形如_n的占位符,n是一个正整数,它们占据了传递给newCallable的参数的位置。n表示生成的可调用对象的参数的位置:如_1为newCallable的第1个参数,_2为newCallable的第2个参数,_3为newCallable的第3个参数,以此类推,_1/_2/_3…这些占位符都在一个叫placeholders的命名空间中。

#include <functional>
using namespace placeholders;int Sub(int a, int b)
{return a - b;
}int main()
{// _1代表sub1的第一个参数,_2代表sub1的第二个参数。// bind内写成_2, _1的顺序,意味sub1的第二个参数会传给Sub的第一个参数a,sub1的第一个参数会传给Sub的第二个参数bauto sub1 = bind(Sub, _2, _1);cout << Sub(1, 2) << endl; cout << sub1(1, 2) << endl;return 0;
}

在这里插入图片描述
这是只改变参数顺序的一般用法。

bind还有最常用的改变参数个数用法,这个用法一般是为了绑死某些参数,使之为一个固定值,使用时就不需要再传参:

#include <functional>
using namespace placeholders;int Sub(int a, int b)
{return a - b;
}int main()
{// _1代表sub2的第一个参数,100代表绑死Sub的第一个参数a,a的值固定为100了// a的值固定了,传参时就不需要传给a,sub2的第一个参数就会传给Sub的第二个参数bauto sub2 = bind(Sub, 100, _1);cout << Sub(1, 2) << endl;cout << sub2(1);return 0;
}

在这里插入图片描述

再比如,刚才上面讲到function包装类成员函数时说到,使用包装后的对象时还需要传给this指针一个参数。有了bind就可以提前绑死这个参数,后续每次使用就不需要额外传了:

#include <functional>
using namespace placeholders;class Plus
{
public:Plus(int n = 10):_n(n){}double plusd(double a, double b){return (a + b) * _n;}
private:int _n;
};int main()
{function<double(double, double)> f = bind(&Plus::plusd, Plus(), _1, _2);cout << f(1, 2) << endl;return 0;
}

在这里插入图片描述

本篇完,感谢阅读。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL高级特性详解

MySQL高级特性详解 一、自关联查询 概念 自关联查询是指一个表与它自己进行连接的查询。通常用于处理具有层级关系或递归结构的数据。 应用场景 员工与上级关系分类的父子关系地区的层级关系 示例 -- 创建员工表 CREATE TABLE employees (emp_id INT PRIMARY KEY,emp_name VARC…

深度学习——调整学习率

学习率调整方法详解在深度学习训练过程中&#xff0c;学习率&#xff08;Learning Rate, LR&#xff09; 是影响模型收敛速度和效果的关键超参数。学习率过大可能导致训练不稳定、震荡甚至无法收敛&#xff1b;学习率过小又会导致收敛过慢甚至陷入局部最优。因此&#xff0c;如…

Java分页 Element—UI

前端代码 <div class"block"><span class"demonstration">页数较少时的效果</span><el-paginationlayout"prev, pager, next":total"50"></el-pagination> </div>参考Element-UI total:0, form: …

html中列表和表格的使用

列表一般来说只有一列一列的进行使用&#xff0c;是一维的列表分为三种列表形式<!-- 列表标签ul-li:无序列表&#xff0c;必须用 <ul> 当 “容器”&#xff08;代表 “无序列表”&#xff09;&#xff0c;每个条目用 <li> 包起来&#xff08;代表 “列表项”&am…

大学信息查询平台:一个现代化的React教育项目

一 项目简介大学信息查询平台是一个基于React Vite Tailwind CSS构建的现代化Web应用&#xff0c;专门用于查询中国各大高校的详细信息。该项目不仅功能实用&#xff0c;更在用户体验和界面设计上做到了极致。二 核心功能2.1. 智能大学搜索// 搜索功能核心代码 const searchU…

代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和

代码随想录算法训练营第六天 - 哈希表2 || 454.四数相加II / 383.赎金信 / 15.三数之和 / 18.四数之和454.四数相加II解题思路383.赎金信自己解答&#xff1a;代码随想录讲解暴力做法哈希表15.三数之和双指针优化改进18.四数之和自己的解答系统讲解454.四数相加II 文档讲解&…

FPGA实现流水式排序算法

该算法采用双调排序算法&#xff0c;是一种可流水的递推算法&#xff0c;且算法的消耗时长可算&#xff0c;具体细节参考视频&#xff1a; https://www.bilibili.com/video/BV1S3thzWEnh/?spm_id_from333.1387.homepage.video_card.click&vd_source69fb997b62efa60ae1add…

平衡车 -- MPU6050

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 传感器原理 此外&#xff0c;用陀螺仪获取x,y,z轴的加速度。 初始化 我们现在对MPU6050进行初始化&#xff0c;MPU6050通过I2C总线与单片机进行通信&#xff0c;通过的是PB8和PB…

在电路浪涌测试中,TVS(瞬态电压抑制二极管)的防护效果确实会受到陪测设备中去耦网络(Decoupling Network,DN)的显著影响

在电路浪涌测试中&#xff0c;TVS&#xff08;瞬态电压抑制二极管&#xff09;的防护效果确实会受到陪测设备中去耦网络&#xff08;Decoupling Network&#xff0c;DN&#xff09;的显著影响&#xff0c;这一现象与浪涌能量的传递路径、阻抗匹配及信号完整性密切相关。结合 AD…

Redis之分布式锁与缓存设计

1、分布式锁 1.1、超卖问题/*** 存在库存超卖的不安全问题*/private void deductStock() {int stockTotal Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));if (stockTotal > 0) { // 这里存在多个线程、进程同时判断通过&#xff0c;然后超买…

静态住宅IP的特点

稳定性高&#xff1a;与动态IP地址相比&#xff0c;静态住宅IP不会不定时变更&#xff0c;能确保业务在网络环境中的一致性和连贯性&#xff0c;适合需要长期维持同一身份的场景&#xff0c;如跨境电商业务等3。安全性强&#xff1a;由于其住宅属性&#xff0c;看起来更像是正常…

Linux 编译 Android 版 QGroundControl 软件并运行到手机上

Linux 编译 Android 版 QGroundControl 软件并运行到手机上环境说明操作步骤一、参考上一篇文章在电脑端把环境搭建好二、配置 Qt Creator 的 Android 环境环境说明 电脑系统 Ubuntu 22.04 qgroundcontrol master 分支 Qt 6.8.3 操作步骤 一、参考上一篇文章在电脑端把环境搭…

Python 2025:量化金融与智能交易的新纪元

当Python遇见金融大数据&#xff0c;算法交易正迎来前所未有的技术变革在2025年的技术浪潮中&#xff0c;Python已经从一个"胶水语言"蜕变为金融科技领域的核心驱动力。根据GitHub 2025年度报告&#xff0c;Python在量化金融项目中的使用率增长了217%&#xff0c;在对…

[论文阅读] 人工智能 + 软件工程 | TDD痛点破解:LLM自动生成测试骨架靠谱吗?静态分析+专家评审给出答案

TDD痛点破解&#xff1a;LLM自动生成测试骨架靠谱吗&#xff1f;静态分析专家评审给出答案 论文信息项目详情论文原标题Evaluation of Large Language Models for Generating RSpec Test Skeletons in Ruby on Rails论文链接https://arxiv.org/pdf/2509.04644一段话总结 该研究…

开源PSS解析器1

本章介绍另一个开源PSS解析工具zuspec&#xff1a; zuspec 提供了一组用于处理 actions relationship level 的工具 &#xff08;ARL&#xff09; 模型&#xff0c;主要是使用 Accellera 便携式测试和刺激 &#xff08;PSS&#xff09; 语言描述的模型。ARL 模型用于为数字设计…

26考研——内存管理_内存管理策略(3)

408答疑 文章目录一、内存管理策略1、内存管理的基本原理和要求1.1、相关概念1.2、逻辑地址与物理地址1.3、程序的链接与装入1.4、进程的内存映像1.5、内存保护1.6、内存共享1.7、内存分配与回收1.8、在存储管理中涉及到两个问题2、连续分配管理方式2.1、相关概念2.2、单一连续…

Python爬虫实战:研究Event Handling机制,构建在线教育平台的课程数据采集和分析系统

1. 引言 1.1 研究背景与意义 在大数据时代,互联网作为全球最大的信息载体,蕴含着海量有价值的数据。这些数据涵盖了商业交易、用户行为、社会趋势等多个领域,对企业决策、学术研究和社会管理具有重要参考价值。如何高效、准确地获取这些数据并进行深度分析,成为当前数据科…

docker 安装 redis 并设置 volumes 并修改 修改密码(四)

设置新密码: 127.0.0.1:6379> CONFIG SET requirepass newpassword OK验证新密码: 127.0.0.1:6379> AUTH newpassword OK更新配置文件: 编辑主机的配置文件/data/redis/conf/redis.conf,将requirepass的值修改为新密码: requirepass newpassword重启容器以使配置…

NBA球星知识大挑战:基于 PyQt5 的球星认识小游戏

NBA球星知识大挑战&#xff1a;基于 PyQt5 的球星认识小游戏 代码详见&#xff1a;https://github.com/xiaozhou-alt/NBA_Players_Recognition 文章目录 NBA球星知识大挑战&#xff1a;基于 PyQt5 的球星认识小游戏一、项目介绍二、文件夹结构三、项目实现1. 自定义动画按钮&a…

电磁波成像(X射线、CT成像)原理简介

电磁波成像&#xff08;X射线、CT成像&#xff09;原理简介一、图像形成的一般形式二、可见光成像2.1可见光2.2可见光成像三、其他电磁波成像3.1X射线成像3.2CT成像3.2.1CT成像原理3.2.2CT成像与X射线成像对比3.2.3CT生成三维描述3.3PET成像一、图像形成的一般形式 大多数图像…