Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++11

qt

stdbind

I'm trying to pass a member function as a function pointer so that I don't need to rely on singletons or global functions to handle Qt messages in Qt 5. As far as I can tell my std::function is of the correct type, it has the correct signature, and bind should be allowing me to jam in the implicit this pointer, essentially passing off a member function as a global/un-owned 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 doesn't compile. I can succesfully create my funcPtr variable but passing it into the qInstallMessageHandler function causes 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 have read:

how to pass a member function as a function pointer?

How do you pass a member function pointer?

How to pass a member function as a parameter to a function that doesn't expect it?

Get function pointer from std::function when using std::bind

but none have helped me.

EDIT:

So it has been said that this isn't possible without a singleton or a global funtion... but why? The only difference between a member function and a global function with the same signature is that they don't have the same signature, there is an implicit this pointer as the first parameter to a member function.

Knowing that, why cannot I use std::bind to bridge this gap, by saying 'I know that the function being called takes the this argument before all of the others, force it in there, be the thing that knows about this. That would be so much cleaner than a singleton and a global function is just crap.

like image 363
Troyseph Avatar asked Sep 15 '15 10:09

Troyseph


1 Answers

You are trying to pass a class instance where a function pointer is expected, while no such conversion exists.

You could do something like this:

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

in main.cpp (for example):

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

You still might have to deal with some issues as in singleton classes, but I think it makes sense that there is one message handler or at least one dispatcher that would somehow redirect different message to appropriate handlers. Hope this helps

like image 130
Anorflame Avatar answered Sep 29 '22 15:09

Anorflame