std::function和bind绑定器

本文来自《深入应用C++11 代码优化与工程级应用》

std::function和std::bind,使我们使用标准库函数时更加方便,且还能方便地实现延迟求值。

1.可调用对象(Callable Objects)

可调用对象有如下几种定义:

(1)是一个函数指针

#include<iostream>
using namespace std;void func()
{}int main()
{void(* func_ptr)(void) = &func; //1.函数指针func_ptr();return 0;
}

func_ptr被称做可调用对象

(2)是一个具有operator()成员函数的类对象(仿函数)

#include<iostream>
using namespace std;struct Foo
{void operator()(){}
};int main()
{Foo foo;    //2.仿函数foo();return 0;
}

foo被称做可调用对象

(3)是一个可被转换为函数指针的类对象。

#include<iostream>
using namespace std;struct Bar
{using fr_t = void(*)(void);static void func(void){}operator fr_t(){return func;}
};int main()
{Bar bar;    //3.可被转换为函数指针的类对象bar();return 0;
}

bar被称做可调用对象,其类型被统称为“可调用类型”。   

 类型转换运算符:operator 类型()-CSDN博客

(4)是一个类成员(函数)指针。

#include<iostream>
using namespace std;struct A
{int a_;void men_func(){}
};int main()
{void (A::*mem_func_ptr)(void)   //4.类成员函数指针= &A::men_func;int A::*mem_obj_ptr //类成员指针= &A::a_;A aa;(aa.*mem_func_ptr)();aa.*mem_obj_ptr = 123;return 0;
}

mem_func_ptr,mem_obj_ptr被称做可调用对象

从上面4个例子可以看到,除了类成员函数之外,上面定义涉及的对象均可以像一个函数那样做调用操作。

func_ptr,foo,mem_func_ptr,mem_obj_ptr都被称为可调用对象,这些对象的类型被称为“可调用类型”。

可调用对象的定义中不包括函数类型和函数引用,包括函数指针。

因为函数类型不能用来直接定义对象。

函数引用从某种意义上来说,可以看做一个const的函数指针。

C++中的可调用对象虽然有比较统一的操作形式(除了类成员指针之外,都是后面加括号进行调用),但定义方法五花八门。当我们试图使用统一的方式保存,或传递一个可调用对象时,会非常麻烦。

2.可调用对象包装器---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__ << "(" << a << ") ->: ";return a;}
};class Bar
{
public:int operator()(int a){std::cout << __FUNCTION__ << "(" << a << ") ->: ";return a;}
};int main()
{std::function<void(void)> fr1 = func; //绑定一个普通函数fr1();//绑定一个类的静态成员函数std::function<int(int)> fr2 = Foo::foo_func;std::cout << fr2(123) << std::endl;//绑定一个仿函数Bar bar;fr2 = bar;std::cout << fr2(123) << std::endl;return 0;
}

输出结果: 

func

foo_func(123) ->: 123

operator()(123) ->: 123

当我们给std::function填入合适的函数签名(即一个函数类型,只需要包括返回值和参数表)之后,它就变成了一个可以容纳所有这一类调用方式的“函数包装器” 。

#include<iostream>
#include <functional>class A
{std::function<void()> callback_;
public:A(const std::function<void()>& f): callback_(f){}void notify(void){callback_();}
};class Foo
{
public:void operator()(void){std::cout << __FUNCTION__ << std::endl;}
};int main()
{Foo foo;A aa(foo);aa.notify();return 0;
}

输出:

operator()

可以看出,std::function可以取代函数指针的作用。因为它可以保存函数延迟执行,所以比较适合作为回调函数。 

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

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

相关文章

php elasticsearch/elasticsearch使用apikey访问接口

此处使用的windows版es和kibana。 1.前提&#xff1a;以安装好es和kibana并正常运行&#xff0c;记得保存es安装完成时提示的账号密码。 2.登录kibana,创建索引并加入几条数据,可以通过kibana界面添加或者通过调用接口添加&#xff0c;非重点不赘述了。 3.添加ApiKey, 使用…

Linux 部署 Harbor 镜像仓库详解

文章目录 安装 Docker安装 Harbor访问 Harbor 安装 Docker 本次部署流程使用的是1台阿里云ECS&#xff0c;Ubuntu 22.04&#xff0c;2核4G。 首先需要做的是在当前服务器上&#xff0c;安装好 Docker&#xff0c;参考链接如下&#xff1a; https://blog.csdn.net/weixin_4659…

ESD防静电闸机如何保护汽车电子产品

随着汽车电子技术的快速发展&#xff0c;汽车中集成了越来越多的电子设备&#xff0c;如车载信息娱乐系统、自动驾驶传感器、驾驶辅助系统等。静电放电可能导致电子组件的损坏、性能下降&#xff0c;甚至使整个系统失效。因此&#xff0c;如何有效保护汽车电子产品免受静电损害…

【【自动驾驶】车辆运动学模型】

【自动驾驶】车辆运动学模型 1. 引言2. 以车辆重心为中心的单车模型2.1 模型介绍2.2 滑移角 β \beta β 的推导2.2 航向角 ψ \psi ψ推导过程&#xff1a;2.3 滑移角 β \beta β2.3 Python代码实现2.4 C代码实现 3. 前轮驱动的单车模型3.1 模型介绍3.3 Python代码实现3.4 …

软件I2C的代码

I2C的函数 GPIO的配置——scl和sda都配置为开漏输出 void MyI2C_Init(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);GPIO_InitTypeDef GPIO_InitStruture;GPIO_InitStruture.GPIO_Mode GPIO_Mode_Out_OD;GPIO_InitStruture.GPIO_PinGPIO_Pin_10 | GPIO_Pin_…

Debug-029-el-table实现自动滚动分批请求数据

前情提要 最近做了一个小优化&#xff0c;还是关于展示大屏方面的。大屏中使用el-table展示列表数据&#xff0c;最初的方案是将数据全部返回&#xff0c;确实随着数据变多有性能问题&#xff0c;有时请求时间比较长。这里做的优化就是实现列表的滚动到距离底部一定高度时再次请…

【银河麒麟高级服务器操作系统实例】金融行业TCP连接数猛增场景的系统优化

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 服务器环境以及配置 物理机/虚拟机/云/容器 物理…

项目实战:Qt+OpenCV仿射变换工具v1.1.0(支持打开图片、输出棋盘角点、调整偏移点、导出变换后的图等等)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/143105881 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、Op…

python中frida的安装+frida-server(雷电模拟器)保姆级安装教程

一.安装雷电模拟器 雷电模拟器官网 直接下载安装即可 &#xff08;1&#xff09;打开必要权限 雷电模拟器的设置已完毕 二.安装adb工具 本文以autox.js来实现adb操作 &#xff08;1&#xff09;vscode中下载auto.js插件 &#xff08;2&#xff09;雷电模拟器下载autox.j…

【大模型实战篇】大模型分词算法Unigram及代码示例

1. 算法原理介绍 与 BPE 分词&#xff08;参考《BPE原理及代码示例》&#xff09;和 WordPiece 分词&#xff08;参考《WordPiece原理及代码示例》&#xff09;不同&#xff0c;Unigram 分词方法【1】是从一个包含足够多字符串或词元的初始集合开始&#xff0c;迭代地删除其中的…

Spring Boot Druid 数据库连接池入门

1. Druid 单数据源 1.1 引入依赖 在 pom.xml 文件中&#xff0c;引入相关依赖。 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-insta…

《异常处理与资源管理:构建稳定程序的关键纽带》

#1024程序员节&#xff5c;征文# 在软件开发的广袤领域中&#xff0c;异常处理和资源管理如同两座坚实的基石&#xff0c;共同支撑着程序的稳定运行。它们之间的关系紧密而微妙&#xff0c;对于构建可靠、高效的软件系统起着至关重要的作用。让我们深入探讨异常处理和资源管理…

idea项目搭建的四种方式: 一(以idea2017为例)

目录 1. 普通java项目 2. 普通JavaWEB项目 3. maven的JavaWEB项目 4. maven的java项目 1. 普通java项目 ①点击“Create New Project”&#xff1b; ②选择“Java”&#xff0c;选择自己安装的jdk&#xff0c;点击“Next”&#xff1b; ③填好项目名称和路径&#xff1b;…

【LeetCode】动态规划—2466. 统计构造好字符串的方案数(附完整Python/C++代码)

动态规划—2466. 统计构造好字符串的方案数 题目描述前言基本思路1. 问题定义举例&#xff1a; 2. 理解问题和递推关系动态规划思想&#xff1a;状态定义&#xff1a;状态转移方程&#xff1a;边界条件&#xff1a; 3. 解决方法动态规划方法伪代码&#xff1a; 4. 进一步优化5.…

MATLAB图像检索系统

MATLAB图像检索系统应用背景 基于内容的图像检索&#xff08;CBIR&#xff09;是一个非常热门的研究领域。本文在对颜色特征、形状特征和纹理特征的研究基础上&#xff0c;将三种特征结合在一起&#xff0c;实现了可以自定义权重的综合特征的图像检索系统&#xff0c;并在 平…

推动AI技术研发与应用,景联文科技提供专业高效图像采集服务

景联文科技提供专业图像采集服务&#xff0c;涵盖多个领域的应用需求。 包含人体图像、人脸图像、手指指纹、手势识别、交通道路、车辆监控等图像数据集&#xff0c;计算机视觉图像数据集超400TB&#xff0c;支持免费试采试标。 高质量人像采集服务&#xff1a;支持不同光线条件…

网络知识总结

osi七层模型 osi七层模型分为&#xff1a;应用层&#xff0c;表示层&#xff0c;会话层&#xff0c;传输层&#xff0c;网络层&#xff0c;数据链路层&#xff0c;物理层 应用层&#xff1a;客户端与服务端之间建立一个通话界面表示层&#xff1a;对数据进行语言转换&#xf…

【Unity】Unity Shader学习笔记(八)基础纹理2:高度纹理、法线纹理、模型空间下的法线纹理、切线空间下的法线纹理光照计算

文章目录 凹凸映射法线纹理设置高度纹理&#xff08;Height Map&#xff09;法线纹理&#xff08;Normal Map&#xff09;模型空间的法线纹理切线空间的法线纹理优劣对比 切线空间下的法线纹理光照计算最终效果完整代码TANGENT语义内置宏 TANGENT_SPACE_ROTATIONObjSpaceLightD…

028.魔改浏览器-抓取closed的shadowRoot下的内容

一、什么是Shadow DOM Shadow DOM是一种在web开发中用于封装HTML标记、样式和行为的技术&#xff0c;以避免组件间的样式和脚本冲突。它允许开发者将网页的一部分隐藏在一个独立的作用域内&#xff0c;从而实现更加模块化和可维护的代码结构 二、js操作Shadow DOM // 获取宿…

【火山引擎】AIGC图像风格化 | 风格实践 | PYTHON

目录 1 准备工作 2 实践 代码 效果图 1 准备工作 ① 服务开通 确保已开通需要访问的服务。您可前往火山引擎控制台,在左侧菜单中选择或在顶部搜索栏中搜索需要使用的服务,进入服务控制台内完成开通流程。