微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

std :: bind在堆栈上?

如何解决std :: bind在堆栈上?

我想将 c ++ objcet成员回调func 传递给“ c” lib ,该文件仅具有void *。然后,我使用std :: function注册回调处理程序。但是当我将std :: function *转换为void *时出现问题,似乎std :: function *在转换为void *时被破坏了。

下面是测试代码

#include <iostream>
#include <functional>

class TfLight {
 public:
  void print(int a) {
    std::cout << "TfLight::print " << a << std::endl;
  }
};

class Server {
 public:
  void run(int a) {
    std::function<void(int)>* func = reinterpret_cast<std::function<void(int)>*>(ptr);
    std::cout << func << std::endl;
    (*func)(a);
  }
  
  void register(std::function<void(int)> tf) {
    std::cout << (&tf) << std::endl;
    // f = tf;
    setPtr(&tf);
  }
  
  void setPtr(void* p) {
    ptr = p;
  }
  
  std::function<void(int)> f;
  void* ptr;
};

int main()
{
    TfLight* tf = new TfLight();
    Server* server = new Server();
    server->register(std::bind(&TfLight::print,tf,std::placeholders::_1));
    server->run(3333);
    
    delete server;
    delete tf;
}

当我使用全局变量保存“ std :: function ”时,可以正常调用它。我该如何解决这个问题?

但是当我将std :: function *转换为void *时出现问题,似乎std :: function *在转换为void *时被破坏了

解决方法

std::bind是一个函数。它不在堆栈或堆中。

其返回值是一个临时对象,并且具有通常的临时寿命。这不是这里的问题。返回值bind存储在传递给std::function的{​​{1}}中。

register中,再次遵循常规的C ++规则。 register是一个函数参数,因此std::function<void(int)> tf)在调用期间一直有效。 &tf返回后,register便不复存在。注释掉的代码是正确的;您应该已经将其复制到tf

由于您拥有Server::f,因此Server::f似乎毫无意义。是的,您可以将void* Server::ptr设置为ptr,但是为什么呢?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。