我正在将回调注册到类中的哈希映射来处理各种事件,所以我使用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;
答案 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可能会导致变通方法。我无法提供任何帮助,因为您没有提供最小的工作示例。在创建时,您可能会发现出现问题或让人们发现您的错误。