How to use bind to pass a member function as a function pointer?

I am trying to pass a member function as a function pointer, so I don’t need to rely on single or global functions to handle Qt messages in Qt 5. As far as I can tell, my std :: function is of the right type, it has the correct signature, and the binding should allow me to get stuck in an implicit pointer this, essentially passing a member function as global / not belonging to the function.

void ProgramMessageHandler::setAsMessageHandlerForProgram() {
    std::function<void(QtMsgType, const QMessageLogContext &, const QString &)> funcPtr;

    funcPtr = std::bind(handleMessages, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);

    qInstallMessageHandler(funkPtr);
}

This does not compile. I can successfully create my variable funcPtr, but passing it to a function qInstallMessageHandlercalls the following:

log\ProgramMessageManager.cpp:16: error: cannot convert 'std::function<void(QtMsgType, const QMessageLogContext&, const QString&)>' to 'QtMessageHandler {aka void (*)(QtMsgType, const QMessageLogContext&, const QString&)}' for argument '1' to 'void (* qInstallMessageHandler(QtMessageHandler))(QtMsgType, const QMessageLogContext&, const QString&)'
 oldHandler = qInstallMessageHandler(hackedPointerToHandleFunction);
                                                                  ^

I read:

How to pass a member function as a function pointer?

How to pass a pointer to a member function?

How to pass a member function as a parameter to a function that does not expect this?

std:: function std:: bind

.

EDIT:

, , ... ? - , , - this.

, std::bind , : " , this , , , this. , , - .

+4
2

, , .

- :

class ProgramMessageHandler
{
  static void  myMessageHandler(QtMsgType, const QMessageLogContext &, const QString &);
};

main.cpp():

...
qInstallMessageHandler(ProgramMessageHander::myMessageHandler);
...

, , , , , - . ,

+2

std::bind - , , , . this std::function can, " ".

-, , , - this:

class ProgramMessageHandler {
private:
  static ProgramMessageHandler* currentHandler;
  void handleMessagesImpl(const std::string& message);
public:
  void setAsMessageHandlerForProgram(){
    currentHandler = this;
    qInstallMessageHandler(handleMessages);
  }
  static void handleMessages(const std::string& message) { 
    if (currentHandler) 
      currentHandler->handleMessagesImpl(message);
  }
};

ProgramMessageHandler* ProgramMessageHandler::currentHandler = nullptr;

int main() {
  ProgramMessageHandler handler;
  handler.setAsMessageHandlerForProgram();

  // trigger messages...
}

.

+1

Source: https://habr.com/ru/post/1607434/


All Articles