No, I do plan to stick with Qt5, and may not need to go older than Qt 5.8 (the last to support OS X 10.9) and don't really want to go older than 5.6 .
Looking at the 5.10 sources I'd have to derive QSlotObjectBase class (looks like that might work) but also provide a custom QFunctorSlotObject class, to be used via a QFunctorSlotObjectWithNoArgs template. That one has a static void impl() function, and the instance I'd create gets handed to the QMetaCallEvent ctor, meaning I'd probably have to derive that class too in hope that gets me deep enough?
I wonder if I didn't already try to go down this rabbit hole once for Qt 5.9 . I'd forgotten, but invokeMethod support for "functors" is actually among the tidbits that I ended up backporting to my patched Qt 5.9 . This time I'm not planning to "just patch Qt already" ;)
Googling for a lib[std]c++ mechanism to execute a function on a specific thread I found this answer: https://stackoverflow.com/a/21653558/1460868 , suggesting in particular this bit of code:
void postToMainThread(std::function<void()> && fun) {
QObject signalSource;
QObject::connect(&signalSource, &QObject::destroyed, qApp, [fun(std::move(fun))](QObject*){
fun();
});
}
It appears to do the trick (at the cost of some additional overhead due to the temp. object). There's also
namespace detail {
template <typename F>
struct FEvent : public QEvent {
using Fun = typename std::decay<F>::type;
Fun fun;
FEvent(Fun && fun) : QEvent(QEvent::None), fun(std::move(fun)) {}
FEvent(const Fun & fun) : QEvent(QEvent::None), fun(fun) {}
~FEvent() { fun(); }
}; }
template <typename F>
static void postToObject(F && fun, QObject * obj = qApp) {
QCoreApplication::postEvent(obj, new detail::FEvent<F>(std::forward<F>(fun)));
}
In both cases I'd need to verify if they do synchronous execution and, if not, figure out how to make them that.
EDIT: note to self: the 1st solution requires C++14, the second is C++11 compatible.