C++实用技术(二)std::function和bind绑定器
目录
- 简介
- std::function
- std::function对象包装器
- std::function做回调函数
- std::bind绑定器
- bind绑定普通函数
- bind绑定成员函数
简介
C++11新增了std::function和std::bind。用于函数的包装以及参数的绑定。可以替代一些函数指针,回调函数的场景。
std::function
std::function对象包装器
std::function是可调用对象的包装器,它可以用来用统一的方式来处理函数、函数对象、函数指针,并允许保存和延迟执行它们。比较难理解,可以从代码上深入:
#include <iostream>
#include <functional>void func(void)
{std::cout << __FUNCTION__ << std::endl;
}class Foo
{
public:static int foo_func(int a){std::cout << __FUNCTION__ << " :input param:" << a << std::endl;return a;}
};
class Bar
{
public:int operator()(int a){std::cout << __FUNCTION__ << " :input param:" <<a<< std::endl;//return a;}
};
int main()
{std::function<void(void)> fr1 = func;//绑定普通函数fr1();std::function<int(int)> fr2 = Foo::foo_func;//绑定一个类的静态成员函数std::cout << "result:"<< fr2(123) << std::endl;Bar bar;std::function<int(int)> fr3 = bar;//绑定一个仿函数//fr2 = bar;//这里用fr2也可以,因为这两个函数的返回值和参数表是一样的std::cout << "result" <<fr3(123) << std::endl;return 0;
}
注意:代码中__FUNCTION__是预定义标识符,基本功能是实现返回所在函数的名字,便于调试日志打印。
运行结果:

可以看出使用给std::function赋值上对应的函数返回值和函数参数表,它就可以容纳这一类调用方式的函数,被称为“函数包装器”。如上述的fr2可以容纳Foo::foo_func和bar。
这里可以看出function类似于函数指针的作用,可以保存各种类型的函数地址。
std::function做回调函数
#include <iostream>
#include <functional>class A
{std::function<void(int)> callback_;
public:A(const std::function<void(int)>& f) : callback_(f) {}void notify(int a){callback_(a);}
};
class Foo
{
public:void operator()(int a){std::cout << __FUNCTION__ <<" a:" << a << std::endl;}
};
int main()
{Foo foo;A aa(foo);aa.notify(111);return 0;
}
这里可以看出function可以取代函数指针的作用,可以用function保存函数延迟执行,所有比较适合用在回调函数场景。
std::bind绑定器
std::bind可以将可调用对象和其参数一起绑定,绑定后的结果可以用std::function进行保存。
其中绑定普通函数和绑定成员函数的写法有所不同。
bind绑定普通函数
#include <iostream>
#include <functional>void input(int x)
{std::cout << x << std::endl;
}int main()
{std::function<void(int)> fr = std::bind(input, std::placeholders::_1);auto fr1 = std::bind(input, std::placeholders::_1);//这里用auto接收也行fr(2);fr1(3);return 0;
}
其中std::placeholders::_1是一个占位符,表示这个位置将在函数调用时,被传入的第一个参数替代。
占位符的使用方法:
#include <iostream>
#include <functional>void input(int x, int y)
{std::cout << x << " " << y << std::endl;
}int main()
{std::function<void(int, int)> fr = std::bind(input, std::placeholders::_1, 2);//这里用auto接收也行fr(4, 5);//4 2fr = std::bind(input, 2, std::placeholders::_1);fr(4, 5);//2 4fr = std::bind(input, std::placeholders::_1, std::placeholders::_2);fr(4, 5);//4 5fr = std::bind(input, std::placeholders::_2, 2);fr(4, 5);//5 2fr = std::bind(input, 2, std::placeholders::_2);fr(4, 5);//2 5return 0;
}
结果:

在绑定参数时,可以通过占位符std::placeholders来决定空位参数会属于调用发生时的第几个参数。
bind绑定成员函数
bind可以绑定成员函数和成员变量。其中绑定成员函数和绑定普通函数时是有一些差别的。
#include <iostream>
#include <functional>class MyClass {
public:int i_ = 0;void foo(int a, int b) {std::cout << a << " " << b << std::endl;}
};int main() {MyClass obj;auto boundFunc = std::bind(&MyClass::foo, &obj, std::placeholders::_1, std::placeholders::_2);//绑定成员函数boundFunc(3, 4);auto fr_i = std::bind(&MyClass::i_, &obj);//绑定成员变量fr_i() = 123;return 0;
}
当使用 std::bind 绑定成员函数时,需要注意以下几点:
- 需要使用成员函数的指针或函数对象来进行绑定。对于指针,需要使用 & 取址符号获取成员函数的地址。
- 需要提供对象的指针(或引用)作为第一个参数,以便在调用时正确地调用成员函数。
可以看到绑定普通函数时是不需要提供对象的指针或引用作为参数。
相关文章:
C++实用技术(二)std::function和bind绑定器
目录 简介std::functionstd::function对象包装器std::function做回调函数 std::bind绑定器bind绑定普通函数bind绑定成员函数 简介 C11新增了std::function和std::bind。用于函数的包装以及参数的绑定。可以替代一些函数指针,回调函数的场景。 std::function std…...
vue框架 element导航菜单el-submenu 简单使用方法--以侧边栏举例
1、目标 实现动态增删菜单栏的效果,所以要在数据库中建表 2 、建表 2.1、表样式 2.2、表数据 3、实体类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.List;Data AllArgsConstructor NoArgsConstr…...
Nodejs 第八章(npm搭建私服)
构建npm私服 构建私服有什么收益吗? 可以离线使用,你可以将npm私服部署到内网集群,这样离线也可以访问私有的包。提高包的安全性,使用私有的npm仓库可以更好的管理你的包,避免在使用公共的npm包的时候出现漏洞。提高…...
React Native获取手机屏幕宽高(Dimensions)
import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接: https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/...
kubernetes基于helm部署gitlab
kubernetes基于helm部署gitlab 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab。 先决条件 已运行的 Kubernetes 集群负载均衡器,为ingress-nginx控制器提供EXTERNAL-IP,本示例使用metallb默认存储类,为gitlab pods提供持久化存储&…...
jmeter 5.1彻底解决中文上传乱码
1.修改源码,然后重新打jar包,就是所有上传文件名重新获取文件名 参考链接:多种Jmeter中文乱码问题处理方法 - 51Testing软件测试网 2.修改Advanced,必须选java...
云运维工具
企业通常寻找具有成本效益的方法来优化创收,维护物理基础架构以托管服务器和应用程序以提供服务交付需要巨大的空间和前期资金,最重要的是,物理基础设施会产生额外的运营支出以进行定期维护,这对收入造成了沉重的损失。 云使企业…...
【RL】Wasserstein距离-GAN背后的直觉
一、说明 在本文中,我们将阅读有关Wasserstein GANs的信息。具体来说,我们将关注以下内容:i)什么是瓦瑟斯坦距离?,ii)为什么要使用它?iii) 我们如何使用它来训练 GAN&…...
sentinel引入CommonFilter类
最近在做一个springcloudAlibaba项目,做链路流控模式时需要将入口资源关闭聚合,做法如下: spring-cloud-alibaba v2.1.1.RELEASE及前,sentinel1.7.0及后: 1.pom 中引入: <dependency><groupId>…...
Phoenix创建local index失败
执行创建local index出现如下错误 0: jdbc:phoenix:hbase01:2181> create local index local_index_name on "test" ("user"."name","user"."address"); 23/07/28 17:28:56 WARN client.SyncCoprocessorRpcChannel: Cal…...
css3 hover border 流动效果
/* Hover 边线流动 */.hoverDrawLine {border: 0 !important;position: relative;border-radius: 5px;--border-color: #60daaa; } .hoverDrawLine::before, .hoverDrawLine::after {box-sizing: border-box;content: ;position: absolute;border: 2px solid transparent;borde…...
jdk安装
JDK的下载、安装和环境配置教程(2021年,win10)_「已注销」的博客-CSDN博客_jdk 以上文章如果没有成功在环境变量中part再添加一句 C:\Program Files (x86)\Java\jdk1.7.0_80\bin 安装目录下的bin目录 写完环境后重启 📎jdk-20_w…...
utf8mb4_general_ci 和utf8mb4_unicode_ci有什么异同,有什么优劣
utf8mb4_general_ci 和 utf8mb4_unicode_ci 都是 MySQL 数据库中的字符集和排序规则(collation)。它们主要用于指定字符数据的排序和比较规则,以确保在数据库中对字符串进行查询和比较时得到正确的结果。 异同点: 1. utf8mb4_gen…...
java实现钉钉群机器人@机器人获取信息后,机器人回复(机器人接收消息)
1.需求 鉴于需要使用钉钉群机器人回复,人们提出的问题,需要识别提出的问题中的关键词,后端进行处理实现对应的业务逻辑 2.实现方式 用户群机器人,附带提出的问题,后端接收消息后识别消息内容,读取到关键…...
ffmpeg转码时出现missing picture in access unit with size 14019
使用ffmpeg录制网络流视频,因为网卡的缘故导致录制中断,视频在转换的时候就出现这个问题。 missing picture in access unit with size 14019怀疑是在最后的地方视频是损坏的,索性截取掉最后的2秒时间,原本视频时长是02:06:28&am…...
以Llama-2为例,在生成模型中使用自定义StoppingCriteria
以Llama-2为例,在生成模型中使用自定义StoppingCriteria 1. 前言2. 场景介绍3. 解决方法4. 结语 1. 前言 在之前的文章中,介绍了使用transformers模块创建的模型,其generate方法的详细原理和使用方法,文章链接: 以be…...
servlet接受参数和乱码问题
servlet接受参数和乱码问题 1、乱码问题 1)get请求 传输参数出现中文乱码问题: 如果还存在问题: 2)post请求 传输参数出现中文乱码问题: 2、接受参数: 3、登录注册案例...
2023-08-05力扣今日三题
链接: 剑指 Offer 22. 链表中倒数第k个节点 题意: 如题 解: 快慢指针 实际代码: #include<iostream> using namespace std; struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {} }; L…...
webpack图片压缩
减少代码体积 | 尚硅谷 Web 前端之 Webpack5 教程 (yk2012.github.io) npm install image-mininizer webpack plugin imagemin -D 无损压缩 npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D 有损压缩 npm install imagemin-gifsicle image…...
JPA使用nativeQuery自定义SQL怎么插入一个对象参数呢?
0、我们在前后端传递数据时候,参数多的情况下,常常将这些参数封装成对象;当有些场景你需要使用JPA nativeQuery自定义SQL,要将这个对象insert时候,初学者似乎有点犯难,jpa不是spring-data项目的内容吗&…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
前端调试HTTP状态码
1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...
零基础在实践中学习网络安全-皮卡丘靶场(第十一期-目录遍历模块)
经过前面几期的内容我们学习了很多网络安全的知识,而这期内容就涉及到了前面的第六期-RCE模块,第七期-File inclusion模块,第八期-Unsafe Filedownload模块。 什么是"遍历"呢:对学过一些开发语言的朋友来说应该知道&…...
如何优雅地绕过限制调用海外AI-API?反向代理与API中转技术详解
阅读时长 | 8分钟 适用读者 | 需要跨境调用OpenAI等AI服务的开发者/企业 一、问题背景:为什么需要代理? 最近在技术社区看到这样的求助: "公司服务器在国内,但业务需要调用OpenAI接口,直接访…...
项目研究:使用 LangGraph 构建智能客服代理
概述 本教程展示了如何使用 LangGraph 构建一个智能客服代理。LangGraph 是一个强大的工具,可用于构建复杂的语言模型工作流。该代理可以自动分类用户问题、分析情绪,并根据需要生成回应或升级处理。 背景动机 在当今节奏飞快的商业环境中,…...
直角坐标系和斜角坐标系
前情概要 笛卡尔坐标系是直角坐标系和斜角坐标系的统称。为什么会有这两种坐标系呢,教材中为什么最后只用直角坐标系呢?我们这样解释: 研究一维空间中的向量时,由于一维空间中的向量有无数条,如果我们选定一条作为基…...
