首页 > 其他分享 >关于callback和std::bind的那些事

关于callback和std::bind的那些事

时间:2023-08-16 18:00:30浏览次数:43  
标签:std function const int bind void callback print

前言

使用callback常常需要绑定类的具体函数,哪些可以绑定哪些不能?

分析

callback不同与普通函数,其入参也是一个函数,具体行为由入参决定
我们看这样一段代码
https://godbolt.org/z/4YTKs567j

#include <functional>
#include <iostream>

class A
{
public:
void print(const int& m)
{
    std::cout << "A::print: " << m << std::endl;
}
};

class B
{
public:
using CallbackType = std::function<void(const int&)>;
void set(const CallbackType& f)
{
    function = f;
}
void run(const int& n)
{
    if(function)
    {
        function(n);
    }
}
private:
    CallbackType function = nullptr;
};

void outPrint(const int& m)
{
    std::cout << "outPrint: " << m << std::endl;
}

int main()
{
    A a{};
    B b{};

    b.set(outPrint);
    b.run(8);
    // b.set(a.print); // won't compile
    b.set(std::bind(&A::print,&a,std::placeholders::_1));
    b.run(7);
    return 0;
}

运行结果

ASM generation compiler returned: 0
Execution build compiler returned: 0
Program returned: 0
outPrint: 8
A::print: 7

其中outPrint()作为外部函数很容易被掉用,比较好理解。
若尝试传入a.print()会报错

<source>: In function 'int main()':
<source>:44:18: error: invalid use of non-static member function 'void A::print(const int&)'
     b.set(a.print); // won't compile
                  ^
<source>:7:6: note: declared here
 void print(const int& m)
      ^~~~~
Compiler returned: 1

一般看到这里会把A::print()注册为static方法使其脱离A成为独立函数,如果A::print()适用了A中其他变量也都需要声明为static类型,也许这能够解决问题,但本质上不能传入的原因是因为A::print()需要两个入参,第一个为编译器隐式传入的thisz指针,因此可以使用std::bind固化部分参数完成函数特化。

总结

对于无法callback的报错不要盲目修改static尽量适用std::bind的方式对函数进行特化减少入参。

标签:std,function,const,int,bind,void,callback,print
From: https://www.cnblogs.com/azureology/p/17635822.html

相关文章

  • cannot import name '_BindParamClause' from 'sqlalchemy.sql.expression'
    python3.8安装环境组件正常安装运行 flaskdbinit报错 cannotimportname'_BindParamClause'from'sqlalchemy.sql.expression' 问题原因-未知 解决方案更新alembic组件版本pipinstall--upgradealembic 问题解决 ......
  • glDebugMessageCallback函数是什么?
    图形编程想要调试并不是一件容易的事,有的时候渲染出全黑的结果基本上只能凭经验来查错,特别是对于着色器,断点日志都是无效的,因此想办法掌握一些调试方法还是有必要的,不然找错误的源头可能真的会非常困难参考:https://blog.csdn.net/Jaihk662/article/details/108801019glDebugMess......
  • c++ std::to_string实现原理
    写这篇的起因是看到MSVCSTL的一个issue,里面提到to_string<int>的实现,正常人的思维是直接除10拿到每位,其实有个更高效的查表法字符串转数字除100拿到两位,并查表填入,少了一半的除法,代价是需要一个201个byte的空间,下面是gcc的实现//Writeanunsignedintegervaluetother......
  • springmvc学习之com.fasterxml.jackson.core:jackson-databind:pom:2.15.2 failed to
    -错误的原因是我们通过坐标依赖导入的jar包没有完全下载,也就是下载了一半就停了,是个下载类型的文件而不是真正的jar包,出现这种错误的原因典型的就比如我这种情况,正在下载的时候断网了,然后这个网络链接突然中断,此时文件就是一个损坏的半成品,Maven中的代码似乎不能像迅雷那样继续下......
  • Android FrameWork——Binder机制详解
    1.前面我曾经发表过一篇blog介绍了aidl实现机制(aidl实现机制浅析),不过那只是停留在java表层,并遗留了一个问题,那就是BinderProxy.transact该方法本地化实现,同时我指出了它的具体代码位置:\frameworks\base\core\jni\android_util_Binder.cpp->staticjbooleanandroid_os_BinderPr......
  • C++ 字符串拼接技巧(stringstream、字符串迭代器、字符串的加法运算符、std::accumulat
    在C++中,经常需要将多个字符串拼接成一个大字符串。这个过程很容易出错,但有一些技巧可以帮助我们轻松地实现这个目标。本文将介绍一些C++中join字符串的技巧。一、使用stringstreamstringstream是一个流。使用它可以将多个字符串连接起来,然后将它们转换为一个字符串。可......
  • std::optional的使用
    optional是一个模板类:template<classT>classoptional;它内部有两种状态,要么有值(T类型),要么没有值(std::nullopt)。有点像T*指针,要么指向一个T类型,要么是空指针(nullptr)。std::optional有以下几种构造方式:#include<iostream>#include<optional>usingnamespacestd;intmai......
  • Node Sass错误问题 Node Sass could not find a binding for your current environmen
    Modulebuildfailed(from./node_modules/sass-loader/dist/cjs.js):Error:MissingbindingD:\2@Html\vue_work_room\blsh-student-view\node_modules\node-sass\vendor\win32-x64-83\binding.nodeNodeSasscouldnotfindabindingforyourcurrentenviron......
  • Android Binder 学习(一) 系统服务的Binder 是如何管理的
    Binder是什么?小编的个人理解1.对于系统来说,Binder类似于血管,链接这ServiceManangerActivityManagerServiceActivityTaskManagerService,承载着他们之间的信息的传递2.对于kernel底层来说,binder是驱动,是一种虚拟的底层驱动3.对于Java应用层来说,他是一个封装了一套序......
  • ISTDP:心灵的深海潜水
    (仅供参考)有一天,我被一种名为ISTDP(IntensiveShort-TermDynamicPsychotherapy,强化短期动态心理治疗)的心理治疗方法所吸引。我决定深入研究这个看似神秘的名字背后的内容。就像一个深海潜水员,我将踏上一个探索我们情感深处、挖掘我们心灵深层防御机制的旅程。1.ISTDP:强化短期动......