std::bind 在堆栈上?

std::bind is on stack?

我想将 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”时,它可以正常调用。我该如何处理这个问题?

But there is a problem when I cast std::function<>* to void*, seems the std::function<>* is destroyed when cast to void*

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

它的 return 值是一个临时对象,并且具有临时对象的通常生命周期。那不是这里的问题; bind return 值存储在传递给 registerstd::function 中。

register中,再次遵循正常的C++规则。 std::function<void(int)> tf) 是函数参数,因此 &tf 在调用期间保持有效。一旦 register returns,tf 不复存在。 commented-out 代码正确;你应该把它复制到 Server::f.

因为你有 Server::fvoid* Server::ptr 似乎完全没有意义。是的,您可以将 ptr 设置为 &f,但是为什么?