c ++回调到另一个成员函数

c++ callbacks to another member function

我有一个关于回调的问题。以前,我将我的回调关联到 class Q

class Q{
   using Callback = std::function<void(char*, int)>;
   Q:Q();
   Q:~Q();

   void Q::RegisterCB(Callback callbackfunc)
   {
       callback_func = callbackfunc;
   }

   void Q:someEvent()
   {
      callback_func();
   }
};

void handleCallback( char*, int)
{
   // perform some routine

}

// from my main file
int main()
{
   Q q;
   q.RegisterCB(&handleCallback);

}

对我来说效果很好。但是,当我需要将 handleCallback 函数转移到另一个 class 以获得更清晰的代码时。我在使用相同代码时遇到问题

class R{

   void R::handleCallback( char*, int)
   {
   // perform some routine

   }

   void R::someOp()
   {
       // q is some member variables of R
       q.RegisterCB(&R::handleCallback, this);

   }

};

但是,我 运行 遇到了一些问题,说有一个“没有匹配的函数来调用......”。我认为这只是简单地从函数名分配给 class 函数名

我可以提示我哪里可能出错吗?

此致

&R::handleCallback 的类型为 void (R::*)(char*, int),无法转换为 std::function<void(char*, int)>
此外,RegisterCB 接受一个参数,而不是两个。

最直接的解决方法是将调用包装在 lambda 函数中,

q.RegisterCB([this](char* p, int x) { handleCallback(p, x); }); 

有关如何使用 lambda 函数将 R 实例的成员函数注册为事件处理程序的示例。 (出于习惯,我用 string_view 替换了 char* ,这对这个例子来说不是必需的)。建议尽可能使用“const”。

#include <functional>
#include <string_view>
#include <iostream>

class Q
{
public:
   // use const arguments, the callback is not supposed to change them
   // just passing information on to callback
   using callback_t = std::function<void(const std::string_view&, const int)>;
   
   // initialize callback with a (lambda) function that does nothing
   // this prevents the need for a check if callback has been set or not
   // (Pattern : Null Strategy)
   Q() :
       m_callback_func( [](const std::string_view&,const int) {} ) 
   {
   }

   ~Q() = default;

   void RegisterCallback(callback_t fn)
   {
       m_callback_func = fn;
   }

   void Event(const std::string_view& string, const int value)
   {
      m_callback_func(string,value);
   }

private:
    callback_t m_callback_func;
};

void handleCallback(const std::string_view& string, const int value)
{
    std::cout << string << ", " << value << "\n";
}

class R
{
public:
    void handleCallback(const std::string_view& string, const int value)
    {
        std::cout << string << ", " << value << "\n";
    }
};

// from my main file
int main()
{
    Q q1;
    q1.RegisterCallback(handleCallback);
    q1.Event("Hello", 42);

    // to pass a callback to an instance of a class 
    // you can use a lambda function https://en.cppreference.com/w/cpp/language/lambda
    R r;
    Q q2;

    q2.RegisterCallback([&r](const std::string_view& string, const int value)
    {
        r.handleCallback(string,value);
    });

    q2.Event("World",21);
    return 0;
}