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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With