C ++绑定到类的回调

时间:2018-04-05 10:01:32

标签: c++ functional-programming std-function stdbind

我正在将回调注册到类中的哈希映射来处理各种事件,所以我使用std::function将它们存储在哈希映射中 我希望将回调绑定到类,以便它们可以访问一些常用方法,因此我使用std::bind来完成此操作。 我不明白为什么第一个例子有效,但当我尝试重构std::bind函数bindEvent时,编译失败。

这样可行:

void MyClass::bindEvent(const QString event, std::function<QJsonObject(const QString &, const QJsonObject &)> handler)
{
   mHandlers.insert(event.toLower(), handler);
}


void MyClass::registerAll()
{

   this->bindEvent(QStringLiteral("do_something"), std::bind(&MyClass::doSomething, this, _1, _2));
   this->bindEvent(QStringLiteral("do_something_else"), std::bind(&MyClass::doSomethingElse, this, _1, _2));
}

这失败了:

void MyClass::bindEvent(const QString event, std::function<QJsonObject(const QString &, const QJsonObject &)> handler)
{
   mHandlers.insert(event.toLower(), std::bind(handler, this, _1, _2));
}


void MyClass::registerAll()
{

   this->bindEvent(QStringLiteral("do_something"), &MyClass::doSomething);
   this->bindEvent(QStringLiteral("do_something_else"), &MyClass::doSomethingElse);
}

错误消息:

../src/MyClass.cpp: In member function ‘virtual bool MyClass::registerAll()’:
../src/MyClass.cpp:124:388: error: no matching function for call to ‘MyClass::bindEvent(QString, QJsonObject (MyClass::*)(const QString&, const QJsonObject&))’
    this->bindEvent(QStringLiteral("do_something"), &MyClass::doSomething);
                                                                                                                                                                                                                                                                                                                                                                                                    ^
../src/MyClass.cpp:124:388: note: candidate is:
../src/MyClass.cpp:109:6: note: void MyClass::bindEvent(QString, std::function<QJsonObject(const QString&, const QJsonObject&)>)
 void MyClass::bindEvent(const QString event, std::function<QJsonObject(const QString &, const QJsonObject &)> handler)
      ^
../src/MyClass.cpp:109:6: note:   no known conversion for argument 2 from ‘QJsonObject (MyClass::*)(const QString&, const QJsonObject&)’ to ‘std::function<QJsonObject(const QString&, const QJsonObject&)>’

哈希本身被声明为

QHash<const QString, std::function<QJsonObject(const QString &, const QJsonObject &)> > mHandlers;

2 个答案:

答案 0 :(得分:2)

第二次尝试失败,因为需要在对象上调用成员函数。当您传递指向成员函数的指针时,没有对象可以调用该函数,因此无法将其转换为std::function

你可以坚持你现在正在做的事情,或者你可以接受bindEvent中指向成员的指针。

void MyClass::bindEvent(const QString event, QJsonObject (MyClass::*handler)(const QString &, const QJsonObject &))
{
   mHandlers.insert(event.toLower(), std::bind(handler, this, _1, _2));
}

这里要指出的另一件事是,从一段时间后推荐使用lambdas而不是std::bind。根据我的理解,它为编译器提供了更好的优化代码的机会。

我个人也觉得它更具可读性。

void MyClass::bindEvent(const QString event, QJsonObject (MyClass::*handler)(const QString &, const QJsonObject &))
{
   mHandlers.insert(event.toLower(), [&, handler](const QString& s, const QJsonObject& o){
      this->*handler(s, o);
   });
}

答案 1 :(得分:1)

我认为问题可能在于它不是一个函数,而是包含在类或命名空间中的函数。您需要在我认为的签名中指定它。

或者使用lambdas可能会导致变通方法。我无法提供任何帮助,因为您没有提供最小的工作示例。在创建时,您可能会发现出现问题或让人们发现您的错误。