Skip to content

QFuture

ModuleCore
Include
#include <QCoroFuture>
CMake
target_link_libraries(myapp QCoro::Core)
QMake
QT += QCoroCore

QFuture, which represents an asynchronously executed call, doesn't have any operation on its own that could be awaited asynchronously, this is usually done through a helper class called QFutureWatcher. To simplify the API, QCoro allows to directly co_await completion of the running QFuture or use of a wrapper class QCoroFuture. To wrap a QFuture into a QCoroFuture, use qCoro():

template<typename T>
QCoroFuture qCoro(const QFuture<T> &future);

It's possible to directly co_await a completion of a QFuture and obtain a result:

const QString result = co_await QtConcurrent::run(...);

This is a convenient alternative to using co_await qCoro(future).result().

result()

Asynchronously waits for the QFuture<T> to finish and returns the result of the future. If the future result type is void, then returns nothing. If the asynchronous operation has thrown an exception, it will be rethrown here.

Example:

QFuture<QString> future = QtConcurrent::run(...);
const QString result = co_await qCoro(future).result();

This is equivalent to using QFutureWatcher and then retrieving the result using QFuture::result():

QFuture<QString> future = QtConcurrent::run(...);
auto watcher = new QFutureWatcher<QString>();
connect(watcher, &QFutureWatcherBase::finished,
        this, [watcher]() {
            watcher->deleteLater();
            auto result = watcher.result();
            ...
        });
watcher->addFuture(future);

takeResult()

Asynchronously waits for the QFuture<T> to finish and returns the result of the future by taking (moving) it from the future object. If the asynchronous operation has thrown an exception, it will be rethrown here.

This is useful when dealing with move-only types (like std::unique_ptr) or when you simply want to move the result instead of copying it out from the future.

Example:

QFuture<std::unique_ptr<Result>> future = QtConcurrent::run(...);
auto result = co_await qCoro(future).takeResult();

This is equivalent to using QFutureWatcher and then retrieving the result using QFuture::takeResult():

QFuture<std::unique_ptr<Result>> future = QtConcurrent::run(...);
auto watcher = new QFutureWatcher<std::unique_ptr<Result>>();
connect(watcher, &QFutureWatcherBase::finished,
        this, [watcher]() {
            watcher->deleteLater();
            auto result = watcher.future().takeResult();
            ...
        });
watcher->addFuture(future);

See documentation for QFuture::takeResult() for limitations regarding moving the result out from QFuture.

This method is only available in Qt 6.

waitForFinished()

This is equivalent to using the result() method.

Example

#include <QCoroFuture>

QCoro::Task<> runTask() {
    // Starts a concurrent task and co_awaits on the returned QFuture. While the task is
    // running, the coroutine is suspended.
    const QString value = co_await QtConcurrent::run([]() {
        QString result;
        ...
        // do some long-running computation
        ...
        return result;
    });
    // When the future has finished, the coroutine is resumed and the result of the
    // QFuture is returned and stored in `value`.

    // ... now do something with the value
}