C++std::function和std::bind()的概念
std::function: 一个通用的函数封装器,它允许你存储和调用任何可以被调用的东西,例如函数、函数指针、函数对象、Lambda 表达式等。
std::bind: 用于创建函数对象。一个可调用对象的绑定版本,可以提前绑定某些参数,稍后调用时只需提供剩余的参数。
在某些情况下,你可以将它们结合使用,例如,如果你想创建一个可调用对象,该对象包含绑定的参数,然后将其存储在 std::function 中。这在某些情况下可以提高代码的可读性和灵活性。
示例:
#include <iostream>
#include <functional>int add(int a, int b) {return a + b;
}int main() {// 创建一个绑定了参数的可调用对象,绑定参数为2,// 占位符_1表示稍后调用时传入的第1个参数放在_1这个位置std::function<int(int)> func = std::bind(add, 2, std::placeholders::_1);// 调用 std::functionint result = func(3); // 这里相当于调用 add(2, 3)std::cout << "Result: " << result << std::endl;return 0;
}
将std::function与std::bind一起使用可以提供一些好处,尤其在以下情况下:
-
延迟参数绑定:你可以使用std::bind在创建std::function对象时部分绑定参数,然后稍后再提供其余的参数。这使得你可以在调用可调用对象时动态地确定一些参数值。
-
增强可读性:std::bind允许你清晰地指定参数的绑定方式,这可以提高代码的可读性,特别是当你处理复杂的函数签名时。
-
灵活性:结合使用std::function和std::bind可以让你更容易地操作和传递可调用对象。这对于实现通用接口或处理回调函数时特别有用。
-
减少代码冗余:如果你需要多次调用具有相同部分绑定的可调用对象,结合使用std::function和std::bind可以减少重复的绑定代码。
在不需要提前绑定参数的情况下,可以不使用std::bind()。在C++11引入Lambda表达式后,使用更加灵活和方便。以下是一个示例,演示如何使用 std::function 存储一个普通函数或Lambda表达式
Copy code
#include <iostream>
#include <functional>// 普通函数
int add(int a, int b) {return a + b;
}int main() {// 使用 std::function 存储普通函数std::function<int(int, int)> func1 = add;// 使用 Lambda 表达式std::function<int(int, int)> func2 = [](int a, int b) {return a + b;};int result1 = func1(2, 3); // 调用 add 函数int result2 = func2(4, 5); // 调用 Lambda 表达式std::cout << "Result 1: " << result1 << std::endl;std::cout << "Result 2: " << result2 << std::endl;return 0;
}
考虑这种情况:可调用对象是类的普通成员函数
- 成员函数是跟具体的对象绑定的,它可以操作该对象中的其他成员变量或者调用其他成员函数。成员函数可以做到分辨哪个对象在调用我是因为有隐藏
this指针指向当前调用该函数的对象。 - 比如
obj.funcAdd(1,2),效果实际上是Obj::funcAdd(&obj, 1, 2);。 - 因此如果可调用对象是普通成员函数,我们要绑定一个参数,即指向调用对象的指针。
因此,比较推荐std::function与std::bind()配合使用,或者用lambda表达式
-
当在一个成员函数中创建函数指针指向另一个普通成员函数时,绑定参数为
this#include <iostream> #include <functional>class MyClass { public:void func1(int value) {std::cout << "func1: " << value << std::endl;}void func2(int value) {std::cout << "func2: " << value << std::endl;}void doSome() {// 使用 std::bind 创建 std::function 对象,将其绑定到 func2std::function<void(MyClass*, int)> functionPtr = std::bind(&MyClass::func2, this, std::placeholders::_2);// 调用函数指针,传入对象实例指针和参数functionPtr(42);} };int main() {MyClass obj;obj.doSome();return 0; }当然也可以手动传入this
比如:std::bind(&MyClass::func2, std::placeholders::_1, std::placeholders::_2);
调用:functionPtr(this, 42); -
利用lambda表达式作为可调用对象
#include <iostream> #include <functional>class MyClass { public:void func1(int value) {std::cout << "func1: " << value << std::endl;}void func2(int value) {std::cout << "func2: " << value << std::endl;}void doSome() {// 使用 Lambda 表达式捕获 this 指针std::function<void(int)> functionPtr = [this](int value) {MemberFunction2(value);};// 调用函数指针,不需要传递 this 指针functionPtr(42);} };int main() {MyClass obj;obj.doSome();return 0; } -
还有一种简单的情况:如果是在想存储某个对象的某个成员函数的指针,则需要传入该对象的地址
#include <iostream> #include <functional>class MyClass { public:void func(int value) {std::cout << "func: " << value << std::endl;} };int main() {MyClass obj;// 创建 std::function 对象,提前绑定&obj,如果不绑定则需要手动传入std::function<void(int)> funcPtr = std::bind(&MyClass::func, &obj, std::placeholders::_1);funcPtr(42);return 0; }
相关文章:
C++std::function和std::bind()的概念
std::function: 一个通用的函数封装器,它允许你存储和调用任何可以被调用的东西,例如函数、函数指针、函数对象、Lambda 表达式等。 std::bind: 用于创建函数对象。一个可调用对象的绑定版本,可以提前绑定某些参数&am…...
QT Creator工具介绍及使用
一、QT的基本概念 QT主要用于图形化界面的开发, QT是基于C编写的一套界面相关的类库,如进程线程库,网络编程的库,数据库操作的库,文件操作的库等。 如何使用这个类库:类库实例化对象(构造函数) --> 学习…...
python爬虫13:pymysql库
python爬虫13:pymysql库 前言 python实现网络爬虫非常简单,只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点,方便以后复习。 申明 本系列所涉及的代码仅用于个人研究与讨论,并不会对网站产生…...
权限管理 ACL、RBAC、ABAC的学习
ACL(Access Control List:访问控制列表) 最简单的一种方式,将权限直接与用户或用户组相关联,管理员直接给用户授予某些权限即可。 这种模型适用于小型和简单系统,权限一块较为简单,并且角色和权限的变化较少。 RBAC(R…...
python的re正则表达式
一、正在表达式的方法(): re是Python中用于处理正则表达式的内置库,提供了许多有用的方法。以下是其中几个常用的方法: re.match(pattern, string): 尝试从字符串的开头匹配一个模式,如果匹配成功则返回匹…...
【算法与数据结构】700、LeetCode二叉搜索树中的搜索
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:二叉搜索树的性质:左节点键值 < 中间节点键值 < 右节点键值。那么我们根据此性质&am…...
SpringBoot v2.7.x+ 整合Swagger3入坑记?
目录 一、依赖 二、集成Swagger Java Config 三、配置完毕 四、解决方案 彩蛋 想尝鲜,坑也多,一起入个坑~ 一、依赖 SpringBoot版本:2.7.14 Swagger版本:3.0.0 <dependency><groupId>com.github.xiaoymin<…...
说说你了解的 CDC
分析&回答 什么是 CDC CDC,Change Data Capture,变更数据获取的简称,使用CDC我们可以从数据库中获取已提交的更改并将这些更改发送到下游,供下游使用。这些变更可以包括INSERT,DELETE,UPDATE等。用户可以在以下的场景下使用CDC: 使用f…...
SpingMvc入门
SpingMvc入门 1.MVC Spring的工作流程:2.sping mvc入门3.静态资源处理 前言 Spring MVC是一种基于Java的web应用开发框架,它采用了MVC(Model-View-Controller)设计模式来帮助开发者组织和管理应用程序的各个组件。 1.MVC Spring的…...
JVM的故事——类文件结构
类文件结构 文章目录 类文件结构一、概述二、无关性基石三、Class类文件的结构 一、概述 计算机是只认由0、1组成的二进制码的,不过随着发展,我们编写的程序可以被编译成与指令集无关、平台中立的一种格式。 二、无关性基石 对于不同平台和不同平台的…...
springboot自定义表格(动态合并单元格)
一、需求展示(一个订单多个商品,商品数量不限订单行合并) 二、技术选型(jxls自定义模板) <!-- 版本具体看官网Release,这里我们使用 2.13.0 --><dependency><groupId>org.jxls</group…...
C++零碎记录(二)
3. 调用其他类 3.1 类中有其他的类 #include <iostream> using namespace std;//点和圆关系案例//点类 class Point { public://设置xvoid setX(int x){m_X x;}//获取xint getX(){return m_X;}//设置yvoid setY(int y){m_Y y;}//获取yint getY(){return m_Y;}private…...
数学建模:回归分析
🔆 文章首发于我的个人博客:欢迎大佬们来逛逛 数学建模:回归分析 文章目录 数学建模:回归分析回归分析多元线性回归案例 多项式回归一元多项式回归多元二项式回归 非线性回归逐步回归 回归分析 多元线性回归 案例 首先进行回归分…...
数据库(一)
数据库 1.为什么要使用数据库 如果要存储数据,我们是可以使用文件来存储数据的,但是使用文件管理数据有很多缺点,比如: 不安全,不利于管理,查询,如果要存储大量的数据,使用文件管理…...
【算法与数据结构】106、LeetCode从中序与后序遍历序列构造二叉树
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:首先我们要知道后序遍历数组的最后一个元素必然是根节点,然后根据根节点在中序遍历数组中的…...
kali 安装cpolar内网穿透实现 ssh 远程连接
文章目录 1. 启动kali ssh 服务2. kali 安装cpolar 内网穿透3. 配置kali ssh公网地址4. 远程连接5. 固定连接SSH公网地址6. SSH固定地址连接测试 简单几步通过cpolar 内网穿透软件实现ssh 远程连接kali! 1. 启动kali ssh 服务 默认新安装的kali系统会关闭ssh 连接服务,我们通…...
算法训练 第一周
一、合并两个有序数组 本题给出了两个整数数组nums1和nums2,这两个数组均是非递减排列,要求我们将这两个数组合并成一个非递减排列的数组。题目中还要求我们把合并完的数组存储在nums1中,并且为了存储两个数组中全部的数据,nums1中…...
软件评测师之码制
目录 一、机器数二、码制三、数的表示范围 一、机器数 机器数就是一个数在计算机中的二进制表示,计算机中机器数的最高位是符号位,正数符号位为0,负数符号位为1,机器数包含原码、反码和补码三种表示形式。 二、码制 表现形式数…...
ubuntu18安装cmake27的方法
背景是ubuntu18默认的cmake是3.10 $ apt search cmake Sorting... Done Full Text Search... Done bear/bionic,bionic 2.3.11-1 allgenerate compilation database for Clang toolingcatkin/bionic,bionic 0.7.8-1 allLow-level build system macros and infrastructure for …...
通讯编程006——NodeJS OPC UA Client开发简单教程
本文介绍如何在NodeJS环境下开发OPC UA Client,通过本文可以对OPC UA的基本概念有所了解,掌握OPC UA的本质。相关软件请登录网信智汇(wangxinzhihui.com)。 开发步骤如下: 1)首先需要安装nodejs,要求版本至少是12。 …...
企业级低代码平台JeecgBoot全攻略:从零基础到实战应用
企业级低代码平台JeecgBoot全攻略:从零基础到实战应用 【免费下载链接】jeecg-boot 一款 AI 驱动的低代码平台,提供"零代码"与"代码生成"双模式——零代码模式一句话搭建系统,代码生成模式自动输出前后端代码与建表 SQL&…...
如何在个人电脑上搭建专属的图片搜索引擎:ImageSearch终极指南
如何在个人电脑上搭建专属的图片搜索引擎:ImageSearch终极指南 【免费下载链接】ImageSearch 基于.NET8的本地硬盘千万级图库以图搜图案例Demo和图片exif信息移除小工具分享 项目地址: https://gitcode.com/gh_mirrors/im/ImageSearch 你是否曾经因为找不到某…...
JAVA面试-equals与==的本质区别
Java中 与 equals() 的区别是面试和日常开发的核心知识点,其核心差异在于比较的对象: 是比较引用地址或基本类型的值,而 equals() 是比较对象的内容,但其默认行为与重写密切相关 。 为了清晰地理解,我们可以将比较场…...
AMD显卡AI部署实战指南:ROCm模型运行与性能优化
AMD显卡AI部署实战指南:ROCm模型运行与性能优化 【免费下载链接】ollama-for-amd Get up and running with Llama 3, Mistral, Gemma, and other large language models.by adding more amd gpu support. 项目地址: https://gitcode.com/gh_mirrors/ol/ollama-for…...
利用HunyuanVideo-Foley为游戏开发赋能:动态环境音效与技能音效生成实践
利用HunyuanVideo-Foley为游戏开发赋能:动态环境音效与技能音效生成实践 1. 游戏音效开发的痛点与机遇 在游戏开发过程中,音效设计往往是最容易被低估却又至关重要的环节之一。传统音效制作需要大量预录制音频素材,一个中型游戏项目动辄需要…...
3步实现Web界面设计标注高效交付:面向全栈团队的Sketch Measure应用指南
3步实现Web界面设计标注高效交付:面向全栈团队的Sketch Measure应用指南 【免费下载链接】sketch-measure Make it a fun to create spec for developers and teammates 项目地址: https://gitcode.com/gh_mirrors/sk/sketch-measure 在Web开发项目中&#x…...
如何用快马平台为网站开发公司快速生成企业官网原型,提升方案演示效率
作为一名经常需要快速响应客户需求的网站开发者,我最近发现了一个能大幅提升工作效率的好方法 - 使用InsCode(快马)平台来生成企业官网原型。这个方法特别适合像我们华网三百每年.cn这样需要快速为客户提供方案演示的网站开发公司。 需求分析阶段 当接到一个新客户…...
springboot+vue基于web的蛋糕商城论坛交流系统的设计系统
目录同行可拿货,招校园代理 ,本人源头供货商系统功能模块分析核心功能模块特色功能实现技术难点解决方案性能优化措施项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作同行可拿货,招校园代理 ,本人源头供货商 系统功能模块分析 …...
Claude技能开发实战指南:从入门到精通的认知升级路径
Claude技能开发实战指南:从入门到精通的认知升级路径 【免费下载链接】awesome-claude-skills A curated list of awesome Claude Skills, resources, and tools for customizing Claude AI workflows 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-…...
如何掌握Marzipano全景技术的5个核心技术?
如何掌握Marzipano全景技术的5个核心技术? 【免费下载链接】marzipano A 360 media viewer for the modern web. 项目地址: https://gitcode.com/gh_mirrors/ma/marzipano 探索现代Web全景图开发的奥秘,发现Marzipano如何通过等距柱状投影、立方体…...
