5

我有以下内容:

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 中执行此操作的正确方法是(在 ClassB 的构造函数中):

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

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

4

1 回答 1

6

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;
}

这以非常丑陋为代价来回避功能成本。

于 2012-05-07T14:48:42.563 回答