在 C++11 中将成员函数指定为回调

Specifying a member function as a callback in C++11

本文关键字:回调 函数 成员 C++11      更新时间:2023-10-16

>我有以下内容:

typedef std::function<bool (const std::string&)> SomethingCoolCb;
class ClassA
{
public:
    void OnSomethingCool(const SomethingCoolCb& cb)
    {
        _cb = cb;
    }
private:
    SomethingCoolCb _cb;
};
class ClassB
{
public:
    ClassB();
    bool Juggle(const std::string& arg);
private:
    ClassA _obj;
};
我想指定 ClassB::

Juggle() 成员函数作为对 ClassB::_obj 的回调。 在 C++11 中执行此操作的正确方法是(在 Class B 的构造函数中):

ClassB::ClassB()
{
    _obj.OnDoSomethingCool(
        [&](const std::string& arg) -> bool
        {
            return Juggle(arg);
        });
}

据我了解,编译器将从上面的 lambda 代码中创建一个 std::function 对象。 因此,当调用回调时,它将调用 std::function::operator() 成员,然后它将调用 ClassB::Juggle() 而不是直接调用 ClassB::Juggle()。 除非我对幕后发生的事情有误,否则这一切似乎都有点低效。 有没有更好的方法?

仅在确实需要多态函数时才使用 std::function。否则,请将其设为模板。

若要使成员函数适应函子,请使用std::mem_fn,然后将对象bind到第一个参数,生成的函子可以用作回调。

样本:

#include <string>
#include <functional>
template<typename F>
class ClassA
{
public:
    ClassA(F f) : _cb(f) {}
private:
    F _cb;
};
class ClassB
{
public:
    ClassB() 
  : _obj(std::bind(&ClassB::Juggle, this, 
                   std::placeholders::_1)) 
  {}
  bool Juggle(const std::string& arg) {return true;}
private:
    ClassA<decltype(std::bind(
                      std::declval<bool (ClassB::*)(const std::string&)>()
                      , std::declval<ClassB*>()
                      , std::placeholders::_1
                      ) ) > _obj;
};
int main()
{
  ClassB b;
  return 0;
}

这回避了功能的成本,代价是丑陋得可怕。