Reputation: 338
I have some existing code that uses std::future
/std::promise
that I'd like to integrate with a Qt GUI cleanly.
Ideally, one could just:
std::future<int> future{do_something()};
connect(future, this, &MyObject::resultOfFuture);
and then implement resultOfFuture
as a slot that gets one argument: the int
value that came out of the std::future<int>
. I've added this suggestion as a comment on QTBUG-50676. I like this best because most of my future/promises are not concurrent anyway, so I'd like to avoid firing up a thread just to wait on them. Also, type inference could then work between the future and the slot's parameter.
But it seems to me that this shouldn't be hard to implement using a wrapper Qt object (e.g., a version of QFutureWatcher
that takes a std::future<int>
). The two issues with a wrapper are:
Is there a best-practice to implement this sort of connection? Is there another way that can hook into the Qt main loop and avoid thread creation?
Upvotes: 2
Views: 544
Reputation: 275385
std::future
is missing continuations. The only way to turn the result of a std::future
asynchronously into a function call delivering the result is to launch a thread watching it, and if you want to avoid busy-waiting you need one such thread per std::future
, as there is no way to lazy-wait on multiple future
s at once.
There are plans to create a future with continuation (a then
operation), but they are not in C++ as of c++17 let alone c++11.
You could write your own system of future/promise that mimics the interface of std::future
and std::promise
that does support continuations, or find a library that already did that.
A busy-wait solution that regularly checked if the future was ready could avoid launching a new thread.
In any case, std::experimental::then
would make your problem trivial.
future.then( [some_state](auto future){
try {
auto x = future.get();
// send message with x
} catch( ... ) {
// deal with exception
}
} );
you can write your own std::experimetnal::future
or find an implementation to use yourself, but this functionality cannot be provided without using an extra thread with a std::future
.
Upvotes: 1