c++ std::funciona代替函数指针——结合std::bind

news2024/11/23 12:40:54

一、介绍std::function

std::function是函数模板类(是一个类)。包含在#include <functional> 中。以前没有这个类的时候,我们在想定义一个回调函数指针,非常的麻烦。我们通常这样的定义:

typedef  void(*ptr)(int,int)// 这里的ptr就是一个函数指针

而使用了std::function这个类的时候,我们可以这样使用,来替换函数指针。例如

std::function<void(int ,int)> func;

std::function 是一种通用、多态的函数封装。它的实例能存储、复制及调用任何可调用 (Callable) 目标——函数、 lambda 表达式、 bind 表达式或其他函数对象,还有指向成员函数指针和指向数据成员指针。

它也是对 C++ 中现有的可调用实体的一种类型安全的包裹(相对来说,函数指针的调用不是类型安全的)

二、与std::bind结合


可以将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。std::bind主要有以下两个作用:

  • 将可调用对象和其参数绑定成一个仿函数;
  • 只绑定部分参数,减少可调用对象传入的参数。

1、std::bind绑定普通函数

 double my_divide(double x, double y) { return x / y; };
 int main(int argc, char* argv[])
 {
	 auto fn_half = std::bind(my_divide, std::placeholders::_1, 2);
	 std::cout << fn_half(10) << '\n';                        // 输出为5
	 return 0;
}

2、std::bind绑定一个成员函数

struct Foo {
    void print_sum(int n1, int n2)
    {
        std::cout << n1+n2 << '\n';
    }
    int data = 10;
};
int main() 
{
    Foo foo;
    auto f = std::bind(&Foo::print_sum, &foo, 95, std::placeholders::_1);
    f(5); // 100
}

三、实例

    #include <iostream>  
    #include <vector>  
    #include <list>  
    #include <map>  
    #include <set>  
    #include <string>  
    #include <algorithm>  
    #include <functional>  
    #include <memory>  
    using namespace std;  
    //声明一个模板  
    typedef std::function<int(int)> Functional;  
    //normal function  
    int TestFunc(int a)  
    {  
        return a;  
    }  
    //lambda expression  
    auto lambda = [](int a)->int{return a;};  
    //functor仿函数  
    class Functor  
    {  
    public:  
        int operator() (int a)  
        {  
            return a;  
        }  
    };  
    //类的成员函数和类的静态成员函数  
    class CTest  
    {  
    public:  
        int Func(int a)  
        {  
            return a;  
        }  
        static int SFunc(int a)  
        {  
            return a;  
        }  
    };  
    int main(int argc, char* argv[])  
    {  
        //封装普通函数  
        Functional obj = TestFunc;  
        int res = obj(0);  
        cout << "normal function : " << res << endl;  
        //封装lambda表达式  
        obj = lambda;  
        res = obj(1);  
        cout << "lambda expression : " << res << endl;  
        //封装仿函数  
        Functor functorObj;  
        obj = functorObj;  
        res = obj(2);  
        cout << "functor : " << res << endl;  
        //封装类的成员函数和static成员函数  
        CTest t;  
        obj = std::bind(&CTest::Func, &t, std::placeholders::_1);  
        res = obj(3);  
        cout << "member function : " << res << endl;  
        obj = CTest::SFunc;  
        res = obj(4);  
        cout << "static member function : " << res << endl;  
        return 0;  
    }  

运行后控制台打印如下

 

四、总结

简而言之,std::function 就是函数的容器。比传统的函数指针功能更强大,配合上bind能够解决成员函数指针跟随类的弊端

弊端可参考如下:

【C++】std::function与函数指针_芒果黑的博客-CSDN博客_c++ function 转函数指针

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能小便冲洗器行业市场运行态势及未来发展潜力分析

2023-2029年中国智能小便冲洗器行业市场运行态势及未来发展潜力报告报告编号&#xff1a;1690632免费目录下载&#xff1a;http://www.cninfo360.com/yjbg/jdhy/cwjd/20230105/1690632.html本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以…

Python人工智能之人脸识别face_recognition安装

face_recognition 模块使用系统环境搭建 系统环境 Ubuntu / deepin操作系统Python 3.6pycharm 开发工具 开发环境配置&#xff0c;安装各种系统包 人脸检测基于dlib&#xff0c;dlib依赖Boost和cmake 在windows中如果要使用dlib还是比较麻烦的&#xff0c;如果想省时间可以在…

【关于Linux中----文件系统、inode、软硬链接和动静态库】

文章目录一、理解文件系统和inode二、硬链接与软链接三、动静态库3.1、静态库与动态库3.2、生成静态库3.3、生成动态库一、理解文件系统和inode 在我前几篇博客中谈到的有关文件的话题&#xff0c;它们统一指的都是打开的文件&#xff0c;那么在这里&#xff0c;我要谈一下没有…

Java基础之《netty(22)—netty编码解码机制》

一、编码和解码的基本介绍 1、编写网络应用程序时&#xff0c;因为数据在网络中传输的都是二进制字节码数据&#xff0c;在发数据时就需要编码&#xff0c;接收数据时就需要解码 2、codec&#xff08;编解码器&#xff09;的组成部分有两个&#xff1a;decoder&#xff08;解…

看小红书排行榜,解构热点背后的出圈密码

导语&#xff1a; 随着消费升级&#xff0c;新中式茶饮也悄然“起风了”&#xff0c;传统茶从老一辈人的茶杯里&#xff0c;通过创新再造&#xff0c;成为年轻人的社交“新”头好&#xff0c;其衍生的“围炉煮茶”更成为小红书平台的热门话题。高流量曝光之路背后&#xff0c;…

一个精美的登录界面原来是这样做的

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏 玩归玩闹归闹&#xff0c;别拿java开玩笑 —————————————————— ⭐相关文章⭐ -通过窗口看…

隐形纱窗行业市场经营管理及发展趋势研究分析

2023-2029年中国隐形纱窗行业市场经营管理及发展趋势研究报告报告编号&#xff1a;1690619本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以任何形式复制、传播或输出中华人民共和国境外。任何未经授权使用本报告的相关商业行为都将违反《…

【操作系统】计算机内存管理

1.内存管理目标rom-ram &#xff08;1&#xff09;为啥要做内存管理 计算机不可能所以用户进程和系统所需要的全部程序和数据放入主存&#xff0c;所以操作系统必须对内存空间进行合理有效的分配内存管理功能 内存分配回收&#xff1a;主存储器&#xff08;物理内存&#xff…

UOS系统启动盘制作

UOS系统启动盘制作一、统信启动盘制作工具1、UOS系统1&#xff09;在启动器打开启动盘制作工具![在这里插入图片描述](https://img-blog.csdnimg.cn/d51bf22e25a846cdb99f7f6317e9447f.png)2&#xff09;选择镜像3&#xff09;选择优盘并格式化4&#xff09;开始制作5&#xff…

第06章 面向对象编程(基础部分oop)

1、单独用变量来解决&#xff1a;不利于数据的管理, 把猫的三个属性拆开了。 2、使用数组的方式解决&#xff1a; 数据类型体现不出来&#xff0c;由于数组中的类型是一致的&#xff0c;所有不能体现出不同的数据类型。 只能通过下标的方式获取信息&#xff0c;这样会造成变量…

sql练习题3

学生表练习 1、查询所有的课程的名称以及对应的任课老师姓名 select course.cname,teacher.tname from course inner join teacher on course.teacher_id teacher.tid;2、查询学生表中男女生各有多少人 select gender as 性别,count(gender) as 个数 from student group b…

Java面向对象:封装、JavaBean和综合案例

目录封装基本概念总结如何更好的封装总结JavaBean补充知识&#xff1a;成员变量&#xff0c;局部变量区别综合案例封装 面向对象的三大特征:封装&#xff0c;继承&#xff0c;多态。 封装:告诉我们&#xff0c;如何正确设计对象的属性和方法。 封装的原则:对象代表什么&#x…

Java学习笔记 --- JDBC(2)

一、事务 1、JDBC程序中当一个Connection对象创建时&#xff0c;默认情况下是自动提交事务&#xff1a;每次执行一个SQL语句时&#xff0c;如果执行成功&#xff0c;就会向数据库自动提交&#xff0c;而不能回滚。 2、JDBC程序中为了让多个SQL语句作为一个整体执行&#xff0…

人工智能算法--启发式搜索与估值函数

⬜⬜⬜ &#x1f430;&#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea; (*^▽^*)欢迎光临 &#x1f7e7;&#x1f7e8;&#x1f7e9;&#x1f7e6;&#x1f7ea;&#x1f430;⬜⬜⬜ ✏️write in front✏️ &#x1f4dd;个人主页&#xff1a;陈丹宇jmu &a…

Linux--阻塞信号--信号集--0104 05

1. 阻塞信号 1.1 信号其他相关常见概念 实际执行信号的处理过程称为信号递达。信号从产生到递达之间的状态称为信号未决。进程可以选择阻塞&#xff08;Block&#xff09;某个信号。被阻塞的信号保持在未决状态&#xff0c;直至进程解除对该信号的阻塞&#xff0c;才执行递达…

Qt—事件处理

Qt中&#xff0c;事件作为一个对象&#xff0c;继承自QEvent类&#xff0c;常见的有键盘事件QKeyEvent、鼠标事件QMouseEvent和定时器事件QTimerEvent等。Qt中&#xff0c;任何QObject子类示例都可以接收和处理事件。实际编程中通常实现部件的paintEvent&#xff08;&#xff0…

百度语音+自动驾驶感知+深度学习平台技术解析

HIEV快讯&#xff08;文/戒僧&#xff09;本文将解析三部分技术内容&#xff0c;出自百度2023 Create大会-技术开放日&#xff1a; •百度如何用“手机全双工语音交互”改善使用导航应用的体验 •如何用“上帝视角”BEV技术提升汽车的自动驾驶能力 •如何用百度自研的深度学习平…

k8s常见错误

master节点初始化失败 出现这个原因是因为&#xff0c;我们之前有执行过初始化的命令&#xff0c;然后初始化的时候就会产生一些文件&#xff0c;和占用端口&#xff0c;然后当你再次初始化的时候&#xff0c;就会提示你有些文件已经存在和端口正在被使用&#xff0c;所以我们…

年末高压叠加“阳”后虚弱,双重压力下的测试者们该何去何从

在2022年的最后一个月&#xff0c;国家放开管控&#xff0c;发布“新十条”&#xff0c;不查核酸&#xff0c;不看健康码&#xff0c;以前闻之色变的“小阳人”&#xff0c;十几天后&#xff0c;遍地皆是。 相信大家对这段时间的经历难以忘怀&#xff0c;在刚放开的时候&#x…

【论文阅读笔记】EndoL2H: Deep Super-Resolution for Capsule Endoscopy

论文地址&#xff1a;https://arxiv.org/abs/2002.05459 代码地址&#xff1a;https://github.com/CapsuleEndoscope/EndoL2H 论文小结 顾名思义&#xff0c;本文是胶囊内窥镜领域的超分算法。本文的网络结构是条件对抗网络 空间attention块的方式&#xff0c;实现8倍、10倍和…