このページでは

QFuture Class

template <typename T> class QFuture

QFuture クラスは、非同期計算の結果を表します。詳細...

ヘッダー: #include <QFuture>
CMake: find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core

注: このクラスのすべての関数はスレッドセーフですが、以下の例外があります:

パブリック型

パブリック関数

QFuture()
QFuture(const QFuture<T> &other)
~QFuture()
QFuture<T>::const_iterator begin() const
void cancel()
(since 6.10) void cancelChain()
QFuture<T>::const_iterator constBegin() const
QFuture<T>::const_iterator constEnd() const
QFuture<T>::const_iterator end() const
bool isCanceled() const
bool isFinished() const
bool isResultReadyAt(int index) const
bool isRunning() const
bool isStarted() const
(since 6.0) bool isSuspended() const
(since 6.0) bool isSuspending() const
(since 6.0) bool isValid() const
(since 6.0) QFuture<T> onCanceled(Function &&handler)
(since 6.1) QFuture<T> onCanceled(QObject *context, Function &&handler)
(since 6.0) QFuture<T> onFailed(Function &&handler)
(since 6.1) QFuture<T> onFailed(QObject *context, Function &&handler)
int progressMaximum() const
int progressMinimum() const
QString progressText() const
int progressValue() const
T result() const
T resultAt(int index) const
int resultCount() const
QList<T> results() const
void resume()
(since 6.0) void setSuspended(bool suspend)
(since 6.0) void suspend()
(since 6.0) T takeResult()
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(Function &&function)
(since 6.1) QFuture<QFuture<T>::ResultType<Function>> then(QObject *context, Function &&function)
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(QThreadPool *pool, Function &&function)
(since 6.0) QFuture<QFuture<T>::ResultType<Function>> then(QtFuture::Launch policy, Function &&function)
(since 6.0) void toggleSuspended()
(since 6.4) QFuture<U> unwrap()
void waitForFinished()
QFuture<T> &operator=(const QFuture<T> &other)

詳細な説明

QFuture は、テンプレートパラメータ `T ` によって、非同期計算が生成する結果の型を指定するテンプレートクラスです。

QFuture を使用すると、後ほど利用可能になる 1 つ以上の結果に対してスレッドを同期させることができます。結果は、デフォルトコンストラクタ、コピーコンストラクタ、および場合によっては移動コンストラクタを持つ任意の型であることができます。result()、resultAt()、results()、およびtakeResult() 関数の呼び出し時に結果が利用できない場合、QFuture はその結果が利用可能になるまで待機します。isResultReadyAt() 関数を使用すると、結果が準備ができているかどうかを確認できます。複数の結果を報告する QFuture オブジェクトの場合、resultCount() 関数は連続した結果の数を返します。 つまり、結果を 0 からresultCount() まで順に反復処理することは常に安全です。takeResult() はフューチャーを無効化し、その後、そのフューチャーから結果にアクセスしようとすると、未定義の挙動を引き起こします。isValid() は、結果にアクセス可能かどうかを示します。

QFuture は、Java スタイルのイテレータ(QFutureIterator) とSTL スタイルのイテレータ(QFuture::const_iterator) を提供しています。これらのイテレータを使用することも、フューチャ内の結果にアクセスするもう 1 つの方法です。

ある非同期計算の結果を別の計算に渡す必要がある場合、QFuture はthen() を使用して、複数の連続した計算をチェーンする便利な方法を提供します。onCanceled() は、QFuture がキャンセルされた場合に呼び出されるハンドラを追加するために使用できます。さらに、onFailed() を使用すると、チェーン内で発生したあらゆる失敗を処理できます。 なお、QFutureはエラー処理に例外を利用しています。例外の使用が不可能な場合でも、エラー型をQFutureの型の一部とすることで、QFutureのエラー状態を示すことができます。たとえば、結果や失敗を保持するためにstd::variant、std::anyなどを使用したり、独自の型を作成したりすることができます。

以下の例は、例外を使用せずにエラー処理を行う方法を示しています。 ネットワーク上の場所から大きなファイルを取得するためにネットワークリクエストを送信したいとします。その後、成功した場合はそのファイルをファイルシステムに書き込み、その場所を返したいとします。これらの操作はいずれも、異なるエラーで失敗する可能性があります。そこで、std::variant を使用して結果またはエラーを保持します:

using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>;

enum class IOError { FailedToRead, FailedToWrite };
using IOResult = std::variant<QString, IOError>;

そして、then() を使用して、これら2つの操作を組み合わせます:

QFuture<IOResult> future = QtConcurrent::run([url] {
        //...
        return NetworkReply(QNetworkReply::TimeoutError);
}).then([](NetworkReply reply) {
    if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply))
        return IOResult(IOError::FailedToRead);

    auto data = std::get_if<QByteArray>(&reply);
    // try to write *data and return IOError::FailedToWrite on failure
    //...
});

auto result = future.result();
if (auto filePath = std::get_if<QString>(&result)) {
    // do something with *filePath
}
else
{
    // process the error
}

複数の継続やハンドラを任意の順序で連結することが可能です。例えば:

QFuture<int> testFuture = someIntFuture;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
}).onCanceled([] {
    // Block 2
}).onFailed([] {
    // Block 3
}).then([] {
    // Block 4
}).onFailed([] {
    // Block 5
}).onCanceled([] {
    // Block 6
});

testFuture の状態(キャンセルされた、例外が発生した、結果がある)に応じて、次のonCanceled()、onFailed()、またはthen()が呼び出されます。したがって、testFuture が正常に完了した場合、Block 1 が呼び出されます。これも成功すれば、次のthen()(Block 4 )が呼び出されます。testFuture がキャンセルされたり、例外が発生して失敗したりした場合は、それぞれBlock 2 またはBlock 3 が呼び出されます。その後、次のthen()が呼び出され、この処理が繰り返されます。

注: Block 2 が呼び出され、例外がスローされた場合 、続くonFailed()(Block 3 )がそれを処理します。もしonFailed()とonCanceled()の順序が逆だった場合、例外状態は次の継続へと伝播し、最終的にはBlock 5 で捕捉されることになります。

次の例では、最初のonCanceled() (Block 2) が削除されています:

QFuture<int> testFuture = someIntFuture;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
}).onFailed([] {
    // Block 3
}).then([] {
    // Block 4
}).onFailed([] {
    // Block 5
}).onCanceled([] {
    // Block 6
});

testFuture がキャンセルされると、その状態は次のthen()に伝播され、これもキャンセルされます。したがって、この場合はBlock 6 が呼び出されます。

futureには、継続(continuation)は1つしか持つことができません。次の例を考えてみましょう:

QPromise<int> p;

QFuture<int> f1 = p.future();
f1.then([](int) { qDebug("first"); });

QFuture<int> f2 = p.future();
f2.then([](int) { qDebug("second"); });

p.start();
p.addResult(42);
p.finish();

この場合、f1 とf2 は、同じ内部状態を共有しているため、実質的に同じ QFuture オブジェクトとなります。その結果、f2 に対してthen を呼び出すと、f1 に指定された継続が上書きされます。したがって、このコードが実行されると、"second" のみが出力されます。

QFuture では、実行中の計算とやり取りする方法も提供されています。例えば、cancel() 関数を使用して計算をキャンセルできます。計算を一時停止または再開するには、setSuspended() 関数、あるいはsuspend()、resume()、toggleSuspended() といった利便性向上のための関数のいずれかを使用します。 実行中の非同期計算のすべてがキャンセルまたは一時停止できるわけではない点に注意してください。たとえば、QtConcurrent::run() によって返されるフューチャーはキャンセルできませんが、QtConcurrent::mappedReduced() によって返されるフューチャーはキャンセル可能です。

進行状況情報は、progressValue()、progressMinimum()、progressMaximum()、およびprogressText() 関数によって提供されます。waitForFinished() 関数は、呼び出し元のスレッドをブロックして計算が完了するまで待機させ、すべての結果が利用可能になることを保証します。

QFuture で表される計算の状態は、isCanceled()、isStarted()、isFinished()、isRunning()、isSuspending()、またはisSuspended() 関数を使用して照会できます。

QFuture<void> は、結果取得関数を一切含まないよう特化されています。また、任意の QFuture<T> を QFuture<void> に代入したりコピーしたりすることも可能です。これは、実際の結果データではなく、ステータスや進行状況の情報のみが必要な場合に便利です。

シグナルとスロットを使用して実行中のタスクとやり取りするには、QFutureWatcher を使用します。

また、QtFuture::connect() を使用すると、シグナルが発行された際に解決される QFuture オブジェクトにシグナルを接続できます。これにより、QFuture オブジェクトと同様にシグナルを扱うことが可能になります。例えば、then() と組み合わせることで、シグナルに複数の継続をアタッチでき、それらは同じスレッドまたは新しいスレッドで呼び出されます。

QtFuture::whenAll() およびQtFuture::whenAny() 関数を使用すると、複数のフューチャーを組み合わせ、それらの最後または最初のものが完了したタイミングを追跡することができます。

値を持つ準備済みの QFuture オブジェクトや、例外を保持する QFuture オブジェクトは、便利関数QtFuture::makeReadyVoidFuture()、QtFuture::makeReadyValueFuture()、QtFuture::makeReadyRangeFuture()、およびQtFuture::makeExceptionalFuture() を使用して作成できます。

注:一部の API(QFuture::then() や、さまざまなQtConcurrent メソッドのオーバーロードを参照)では、特定のスレッドプールで計算をスケジュールすることができます。ただし、QFuture はデッドロックを防止し、スレッドの使用を最適化するために、ワークスティールアルゴリズムを実装しています。その結果、計算は QFuture の結果を要求したスレッド内で直接実行される可能性があります。

注: 計算を開始し 、結果を QFuture に格納するには 、QPromise または Qt Concurrent フレームワーク内のAPIのいずれかを使用してください。

関連項目: QPromise 、QtFuture::connect()、QtFuture::makeReadyVoidFuture()、QtFuture::makeReadyValueFuture()、QtFuture::makeReadyRangeFuture()、QtFuture::makeExceptionalFuture()、QFutureWatcher 、および Qt Concurrent。

メンバ型のドキュメント

QFuture::ConstIterator

QFuture::const_iterator の Qt スタイルの同義語。

メンバ関数のドキュメント

QFuture::QFuture()

空の、キャンセル済みのフューチャーを構築します。

QFuture::QFuture(const QFuture<T> &other)

other のコピーを作成します。

operator=()も参照してください 。

QFuture::~QFuture()

未来を破壊します。

なお、これは非同期計算を待機させたりキャンセルしたりするものではありません。フューチャーが破棄される前に計算が確実に完了するようにする必要がある場合は、waitForFinished() またはQFutureSynchronizer を使用してください。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::begin() const

future 内の最初の結果を指す、STL スタイルのconstイテレータを返します。

constBegin() およびend()も参照してください 。

void QFuture::cancel()

このフューチャーが表す非同期計算をキャンセルします。なお、キャンセル処理自体は非同期で行われる点に注意してください。同期的なキャンセルが必要な場合は、cancel() を呼び出した後に `waitForFinished()` を使用してください。

キャンセルされたフューチャーでも、現在利用可能な結果には引き続きアクセスできますが、この関数を呼び出した後は新しい結果が利用可能になることはありません。このフューチャーを監視しているQFutureWatcher オブジェクトは、キャンセルされたフューチャーに対して進行状況や結果の準備完了シグナルを配信しません。

実行中の非同期計算のすべてがキャンセルできるわけではない点に注意してください。たとえば、QtConcurrent::run() によって返されるフューチャーはキャンセルできませんが、QtConcurrent::mappedReduced() によって返されるフューチャーはキャンセル可能です。

cancelChain()も参照してください 。

[since 6.10] void QFuture::cancelChain()

継続チェーン全体をキャンセルします。すでに完了したフューチャーはすべて変更されず、その結果は引き続き利用可能です。保留中の継続はすべてキャンセルされ、継続チェーン内にonCanceled()ハンドラが存在する場合は、それが呼び出されます。

auto f = QtConcurrent::run([] {/*...*/})
                .then([]{
                    // Then 1
                })
                .then([]{
                    // Then 2
                })
                .onCanceled([]{
                    // OnCanceled 1
                })
                .then([]{
                    // Then 3
                })
                .then([]{
                    // Then 4
                })
                .onCanceled([]{
                    // OnCanceled 2
                });
//...
f.cancelChain();

この例では、Then 2 の継続が実行される前にチェーンがキャンセルされた場合、OnCanceled 1 とOnCanceled 2 の両方のキャンセルハンドラが呼び出されます。

チェーンが `Then 2` の後に、`Then 4` の前にキャンセルされた場合、`OnCanceled 2 ` のみが呼び出されます。

注: すでに完了しているフューチャーに対してこのメソッドを呼び出しても 、何の効果もありません。上記の例に示されているように、継続チェーン全体を表す `QFuture ` オブジェクトに対して使用することを推奨します。

チェーン内のいずれかの継続が非同期計算を実行し、それを表すQFuture を返す場合、cancelChain() の呼び出しは、そのネストされた計算が開始されると、その内部には伝播されません。 その理由は、futureが継続チェーン内で利用可能になるのは、外側のfutureが履行されたときのみであるのに対し、キャンセルは、外側のfutureとネストされたfutureの両方がまだ計算の完了を待っている間に発生する可能性があるためです。そのような場合、ネストされたfutureを明示的にキャプチャしてキャンセルする必要があります。

QFuture<void> nested;
auto f = createFuture()
            .then([&]{
                nested = runNestedComputation();
                // do some other work
                return nested;
            })
            .unwrap()
            .then([]{
                // other continuation
            })
            .onCanceled([]{
                // handle cancellation
            });
//...
f.cancelChain();
nested.cancel();

この例では、runNestedComputation() がすでに実行中の場合、nested.cancel() を呼び出すことによってのみキャンセルできます。

この関数は Qt 6.10 で導入されました。

cancel()も参照してください 。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constBegin() const

future 内の最初の結果を指す、STL スタイルのconstイテレータを返します。

begin() およびconstEnd()も参照してください 。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::constEnd() const

future内の最後の結果の直後に位置する仮想の結果を指す、STLスタイルのconstイテレータを返します。

constBegin() およびend()も参照してください 。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QFuture<T>::const_iterator QFuture::end() const

future内の最後の結果の直後に位置する仮想の結果を指す、STLスタイルのconstイテレータを返します。

begin() およびconstEnd()も参照してください 。

bool QFuture::isCanceled() const

cancel() 関数によって非同期計算がキャンセルされた場合は `true ` を返し、それ以外の場合は `false` を返します。

この関数が `true` を返した場合でも、計算がまだ実行中である可能性があることに注意してください。詳細については、cancel() を参照してください。

bool QFuture::isFinished() const

このフューチャーが表す非同期計算が完了している場合は `true ` を返し、そうでない場合は `false` を返します。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> bool QFuture::isResultReadyAt(int index) const

index の結果が即座に利用可能な場合は `true ` を返し、そうでない場合は `false` を返します。

注:この関数を呼び出すと 、isValid() がこのQFuture に対してfalse を返す場合、未定義の挙動が生じます。このQFuture がまだ開始されていない場合は、未定義の挙動を避けるために、この関数を呼び出す前にwaitForFinished() を呼び出してください。

resultAt()、resultCount()、およびtakeResult()も参照してください 。

bool QFuture::isRunning() const

このフューチャーが表す非同期計算が現在実行中の場合は `true ` を返し、そうでない場合は `false` を返します。

bool QFuture::isStarted() const

このフューチャーが表す非同期計算が開始されている場合は `true ` を返し、そうでない場合は `false` を返します。

[since 6.0] bool QFuture::isSuspended() const

非同期計算の一時停止が要求され、それが有効になっている場合(つまり、これ以上の結果や進行状況の変更は期待されない場合)、true を返します。

この関数は Qt 6.0 で導入されました。

setSuspended()、toggleSuspended()、およびisSuspending()も参照してください 。

[since 6.0] bool QFuture::isSuspending() const

suspend() 関数によって非同期計算が一時停止されているものの、処理自体はまだ一時停止されておらず、計算が実行中の場合は、true を返します。それ以外の場合は、false を返します。

一時停止が実際に有効になっているかどうかを確認するには、代わりに `isSuspended()` を使用してください。

この関数は Qt 6.0 で導入されました。

setSuspended()、toggleSuspended()、およびisSuspended()も参照してください 。

[since 6.0] bool QFuture::isValid() const

この `QFuture ` オブジェクトから結果にアクセスしたり、結果を取得したりできる場合は `true ` を返します。関連する `QPromise ` がまだ開始されていないか、またはフューチャーから結果がすでに取得済みの場合は `false ` を返します。

注:この関数の戻り値は 、フューチャーの結果が消費可能かどうかを示すだけであり、結果の準備が整っているかどうかは示しません。この関数は、関連するQPromise が開始されているものの、結果の準備がまだ整っていない場合でもtrue を返します。準備が整っているかどうかを確認するには、isResultReadyAt() またはisFinished() を呼び出してください。

この関数は Qt 6.0 で導入されました。

takeResult()、result()、results()、resultAt()、isFinished()、およびisResultReadyAt()も参照してください 。

[since 6.0] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(Function &&handler)

このフューチャーにキャンセル処理handler を関連付けます。返されるフューチャーは、このフューチャーがキャンセルされない限り、このフューチャーとまったく同じ挙動(同じ状態と結果)を示します。handler は、引数を取らず、このフューチャーがパッケージ化する型の値を返す呼び出し可能オブジェクトです。キャンセル後、返されるフューチャーはhandler によって返された値をパッケージ化します。

キャンセル前に登録された場合、handler は、キャンセル後にフューチャーが完了したと報告するスレッドと同じスレッドで呼び出されます。このフューチャーがすでにキャンセルされた後にハンドラーが登録された場合、onCanceled() を実行するスレッドで直ちに呼び出されます。したがって、ハンドラーは、どのスレッドで実行されるかについて常に仮定を立てることはできません。 ハンドラーが呼び出されるスレッドを制御したい場合は、コンテキストオブジェクトを受け取るオーバーロードを使用してください。

以下の例は、キャンセルハンドラの登録方法を示しています:

QFuture<int> testFuture /*...*/;
auto resultFuture = testFuture.then([](int res) {
    // Block 1
    //...
    return 1;
}).then([](int res) {
    // Block 2
    //...
    return 2;
}).onCanceled([] {
    // Block 3
    //...
    return -1;
});

testFuture がキャンセルされると、Block 3 が呼び出され、resultFuture の結果は-1 となります。testFuture とは異なり、これはCanceled 状態にはなりません。つまり、その結果を取得したり、継続を添付したりすることが可能です。

また、継続のチェーンが実行中の間、そのチェーンを開始したフューチャーを介してチェーンをキャンセルできる点にも注意してください。例えば、Block 1 がすでに実行中の状態でtestFuture.cancel() が呼び出されたとします。次の継続はキャンセルが要求されたことを検知するため、Block 2 はスキップされ、キャンセルハンドラ(Block 3 )が呼び出されます。

注:この メソッドは、継続チェーンの結果を表す新しい `QFuture ` を返します。 結果として生成されたQFuture 自体をキャンセルしても、それに至るチェーン内のキャンセルハンドラは呼び出されません。つまり、resultFuture.cancel() を呼び出しても、Block 3 は呼び出されません。resultFuture は、キャンセルハンドラがtestFuture にアタッチされた結果として生成されたフューチャーであるため、resultFuture 自体にはキャンセルハンドラがアタッチされていないからです。testFuture のキャンセル、またはonCancelled() の呼び出し以前にアタッチされた継続によって返されたフューチャーのキャンセルのみが、Block 3 をトリガーすることができます。

この関数は Qt 6.0 で導入されました。

then() およびonFailed()も参照してください 。

[since 6.1] template <typename Function, typename = std::enable_if_t<std::is_invocable_r_v<T, Function>>> QFuture<T> QFuture::onCanceled(QObject *context, Function &&handler)

このフューチャーに、フューチャーがキャンセルされた際に呼び出されるキャンセル処理handler を関連付けます。handler は、引数を一切受け取らない呼び出し可能オブジェクトです。これは、context オブジェクトのスレッド内で呼び出されます。これは、キャンセル処理を特定のスレッドで処理する必要がある場合に役立ちます。

チェーンが完了する前にcontext が破棄された場合、futureはキャンセルされます。詳細については、then()を参照してください。

注: このメソッドを呼び出す際は 、チェーンの設定中にcontext が存続していることが保証されている必要があります。

handler に関する詳細については、他のオーバーロードのドキュメントを参照してください。

これはオーバーロードされた関数です。

この関数は Qt 6.1 で導入されました。

then() およびonFailed()も参照してください 。

[since 6.0] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(Function &&handler)

このフューチャーに失敗ハンドラを登録し、例外を処理します。返されるフューチャーは、このフューチャーが例外で失敗しない限り、このフューチャーとまったく同じように動作します(状態と結果が同じです)。

handler は、引数を一切受け取らないか、または1つの引数を受け取る呼び出し可能オブジェクトであり、catch文と同様に特定のエラータイプでフィルタリングを行います。これは、このフューチャーがパッケージ化する型の値を返します。失敗後、返されるフューチャーはhandler によって返された値をパッケージ化します。

ハンドラは、例外が発生した場合にのみ呼び出されます。このハンドラが登録された後に例外が発生した場合、ハンドラは、その例外の結果としてフューチャーを完了したと報告するスレッド内で実行されます。 このフューチャーがすでに失敗した後にハンドラが登録された場合、onFailed() を実行するスレッド内で、ハンドラは直ちに呼び出されます。したがって、ハンドラは、どのスレッドで実行されるかについて常に仮定を置くことはできません。ハンドラが呼び出されるスレッドを制御したい場合は、コンテキストオブジェクトを受け取るオーバーロードを使用してください。

以下の例は、失敗ハンドラを登録する方法を示しています:

QFuture<int> future = someIntFuture;
auto resultFuture = future.then([](int res) {
    //...
    throw Error();
    //...
    return res;
}).onFailed([](const Error &e) {
    // Handle exceptions of type Error
    //...
    return -1;
}).onFailed([] {
    // Handle all other types of errors
    //...
    return -1;
});

auto result = resultFuture.result(); // result is -1

複数のハンドラが登録されている場合、スローされた例外の型と一致する最初のハンドラが呼び出されます。例えば:

QFuture<int> future = someIntFuture;
future.then([](int res) {
    //...
    throw std::runtime_error("message");
    //...
}).onFailed([](const std::exception &e) {
    // This handler will be invoked
    return -1;
}).onFailed([](const std::runtime_error &e) {
    // This handler won't be invoked, because of the handler above.
    return -1;
});

どのハンドラもスローされた例外の型と一致しない場合、例外は結果となるフューチャーに伝播されます:

QFuture<int> future = someIntFuture;
auto resultFuture = future.then([](int res) {
    //...
    throw Error("message");
    //...
    return res;
}).onFailed([](const std::exception &e) {
    // Won't be invoked
    return -1;
}).onFailed([](const QException &e) {
    // Won't be invoked
    return -1;
});

try {
    auto result = resultFuture.result();
} catch(QException &someException) {
    // Handle the exception
}

注: 引数を取らないハンドラをいつでも添付することで 、すべての例外タイプを処理し、try-catchブロックの記述を省略することができます 。

この関数は Qt 6.0 で導入されました。

then() およびonCanceled()も参照してください 。

[since 6.1] template <typename Function, typename = std::enable_if_t<!QtPrivate::ArgResolver<Function>::HasExtraArgs>> QFuture<T> QFuture::onFailed(QObject *context, Function &&handler)

このフューチャーに失敗ハンドラを登録し、フューチャーがスローする、あるいはすでにスローした例外を処理します。このフューチャーと同じ型のQFuture を返します。 このハンドラは、例外が発生した場合にのみ、context オブジェクトのスレッド内で呼び出されます。これは、特定のスレッドで失敗を処理する必要がある場合に役立ちます。例:

// somewhere in the main thread
auto future = QtConcurrent::run([] {
    // This will run in a separate thread
    //...
    throw std::exception();
}).onFailed(this, [] {
    // Update UI elements
});

QtConcurrent::run に添付された失敗ハンドラは UI 要素を更新するため、非 GUI スレッドからは呼び出すことができません。そのため、this を.onFailed() のコンテキストとして指定し、メインスレッドで確実に呼び出されるようにしています。

チェーンが完了する前にcontext が破棄された場合、フューチャーはキャンセルされます。詳細については、then()を参照してください。

注: このメソッドを呼び出す際は 、チェーンのセットアップ中にcontext が存続していることを保証する必要があります。

handler に関する詳細については、他のオーバーロードのドキュメントを参照してください。

これはオーバーロードされた関数です。

この関数は Qt 6.1 で導入されました。

then() およびonCanceled()も参照してください 。

int QFuture::progressMaximum() const

progressValue() の最大値を返します。

progressValue() およびprogressMinimum()も参照してください 。

int QFuture::progressMinimum() const

progressValue() の最小値を返します。

progressValue() およびprogressMaximum()も参照してください 。

QString QFuture::progressText() const

非同期計算によって報告された進行状況の(オプションの)テキスト表現を返します。

すべての計算が進行状況のテキスト表現を提供するわけではないため、この関数は空の文字列を返す場合があることに注意してください。

int QFuture::progressValue() const

現在の進行状況の値を返します。この値は、progressMinimum() とprogressMaximum() の間の値となります。

progressMinimum() およびprogressMaximum()も参照してください 。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::result() const

将来得られる結果のうち、最初のものを返します。結果がすぐには利用できない場合、この関数はブロックして、結果が利用可能になるのを待ちます。これは、resultAt(0) を呼び出すための便利なメソッドです。 なお、result() は内部に格納された結果のコピーを返します。T が移動専用型である場合、または結果をコピーしたくない場合は、代わりにtakeResult()を使用してください。

注:この関数を呼び出すと 、isValid()がこのQFuture に対してfalse を返す場合、未定義の挙動が生じます。このQFuture がまだ開始されていない場合は、未定義の挙動を回避するために、この関数を呼び出す前にwaitForFinished()を呼び出してください。

resultAt()、results()、およびtakeResult()も参照してください 。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::resultAt(int index) const

将来的にindex にある結果を返します。結果がすぐに利用できない場合、この関数はブロックされ、結果が利用可能になるまで待機します。

注:この関数を呼び出すと 、isValid()がこのQFuture に対してfalse を返した場合、未定義の挙動が生じます。このQFuture がまだ開始されていない場合は、未定義の挙動を避けるために、この関数を呼び出す前にwaitForFinished()を呼び出してください。

result()、results()、takeResult()、およびresultCount()も参照してください 。

int QFuture::resultCount() const

このフューチャーで利用可能な連続した結果の数を返します。結果セットに欠落があるため、実際に格納されている結果の数はこの値と異なる場合があります。結果を 0 から resultCount() まで順に処理することは、常に安全です。

関連項目: result()、resultAt()、results()、およびtakeResult()。

template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> QList<T> QFuture::results() const

フューチャーからのすべての結果を返します。結果がすぐに利用できない場合、この関数はブロックされ、結果が利用可能になるまで待機します。なお、results() は、内部に格納された結果のコピーを返す点に注意してください。 現在、移動専用型T のすべての結果を取得することはサポートされていません。ただし、STLスタイルのイテレータや読み取り専用のJavaスタイルのイテレータを使用することで、移動専用結果のリストを反復処理することは可能です。

注:この関数を呼び出すと 、isValid() がこのQFuture に対してfalse を返す場合、未定義の挙動が生じます。このQFuture がまだ開始されていない場合は、未定義の挙動を避けるために、この関数を呼び出す前にwaitForFinished() を呼び出してください。

result()、resultAt()、takeResult()、resultCount()、およびisValid()も参照してください 。

void QFuture::resume()

future() で表される非同期計算を再開します。これは、単に `setSuspended(false)` を呼び出すだけの、利便性を高めるためのメソッドです。

suspend()も参照してください 。

[since 6.0] void QFuture::setSuspended(bool suspend)

suspend がtrueの場合、この関数はfuture()によって表される非同期計算を一時停止します。計算がすでに一時停止されている場合、この関数は何もしません。futureが一時停止されても、QFutureWatcher は進行状況や結果のレディ信号の配信を直ちに停止することはありません。 一時停止の時点でも、進行中で停止できない計算が残っている可能性があります。そのような計算に関するシグナルは引き続き配信されます。

suspend がfalseの場合、この関数は非同期計算を再開します。計算が以前に中断されていなかった場合、この関数は何もしません。

すべての計算がサスペンドできるわけではないことに注意してください。たとえば、QtConcurrent::run() によって返される `QFuture ` はサスペンドできませんが、QtConcurrent::mappedReduced() によって返される `QFuture ` はサスペンド可能です。

この関数は Qt 6.0 で導入されました。

isSuspended()、suspend()、resume()、およびtoggleSuspended()も参照してください 。

[since 6.0] void QFuture::suspend()

このフューチャーによって表される非同期計算を一時停止します。これは、単に `setSuspended(true)` を呼び出すだけの、利便性を高めるためのメソッドです。

この関数は Qt 6.0 で導入されました。

resume()も参照してください 。

[since 6.0] template <typename U = T, typename = QtPrivate::EnableForNonVoid<U>> T QFuture::takeResult()

isValid() がtrue を返す場合にのみ、この関数を呼び出してください。それ以外の場合は、動作が未定義となります。この関数は、QFuture オブジェクトから最初の結果を取得(移動)します。ただし、結果が1つだけ期待される場合に限ります。他に結果がある場合は、最初の結果を取得した後、それらは破棄されます。 結果がすぐに利用できない場合、この関数はブロックし、結果が利用可能になるまで待機します。QFuture は、可能であれば移動セマンティクスを使用しようとしますが、型が移動不可能である場合はコピー構築にフォールバックします。結果が取得された後、isValid()はfalse として評価されます。

注: QFuture は 、一般的に異なるQFuture オブジェクト間(場合によっては異なるスレッド間)で結果を共有することを許可しています。takeResult()は、QFuture が移動専用型(std::unique_ptrなど)でも機能するように導入されたため、結果をフューチャーから移動できるスレッドは1つだけであり、その操作は1回のみ行われることを前提としています。 また、現時点ではすべての結果のリストを取得することはサポートされていません。ただし、STL スタイルのイテレータや読み取り専用のJava スタイルのイテレータを使用することで、移動専用結果のリストを反復処理することは可能です。

この関数は Qt 6.0 で導入されました。

result()、results()、resultAt()、およびisValid()も参照してください 。

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(Function &&function)

このフューチャーに継続を関連付け、Sync ポリシーを使用して、必要に応じて複数の非同期計算を連鎖させることができます。function は、このフューチャーに結果がある場合(QFuture<void>ではない場合)、このフューチャーによってパッケージ化された型の引数を受け取る呼び出し可能オブジェクトです。 それ以外の場合は、引数を一切受け取りません。このメソッドは、function が返す型の値をパッケージ化した新しいQFuture を返します。返されたフューチャーは、添付された継続が呼び出されるか、このフューチャーが失敗するか、またはキャンセルされるまで、初期化されていない状態のままとなります。

注: 継続を別のスレッドで起動する必要がある場合は、このメソッドの他のオーバーロードを使用してください 。

次のように、複数の操作を連鎖させることができます:

QFuture<int> future = ...;
future.then([](int res1){ ... }).then([](int res2){ ... })...

あるいは:

QFuture<void> future = ...;
future.then([](){ ... }).then([](){ ... })...

継続は、その値の代わりに、前のフューチャーを表す `QFuture ` 型の引数を受け取ることもできます。これは、例えば `QFuture ` が複数の結果を返し、ユーザーが継続内でそれらにアクセスしたい場合などに便利です。あるいは、複数の継続の連鎖を中断しないように、ユーザーが継続内で前のフューチャーの例外を処理する必要がある場合にも役立ちます。例えば:

QFuture<int> future = someIntFuture;
    future.then([](QFuture<int> f) {
        try {
            //...
            auto result = f.result();
            //...
        } catch (QException &e) {
            // handle the exception
        }
    }).then([](){/*...*/});

警告: 前のフューチャーにT 型の結果が複数含まれており、継続がT 型の引数をパラメータとして受け取る場合 、前のQFuture からの最初の結果のみが継続内で処理されます!

前のフューチャーが例外をスローし、それが継続内部で処理されない場合、呼び出し側が例外を処理できるように、例外は継続フューチャーに伝播されます:

QFuture<int> future = someIntFuture;
auto continuation = future.then([](int res1){ /*...*/ return res1; }).then([](int res2){ /*...*/ return res2; })/*...*/;
//...
// future throws an exception
try {
    auto result = continuation.result();
} catch (QException &e) {
    // handle the exception
}

この場合、継続のチェーン全体が中断されます。

注: このフューチャーがキャンセルされた場合 、それに紐付けられた継続もキャンセルされます。

これはオーバーロードされた関数です。

この関数は Qt 6.0 で導入されました。

関連項目: onFailed() およびonCanceled()。

[since 6.1] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QObject *context, Function &&function)

このフューチャーにコンティニュエーションを紐付け、必要に応じて複数の非同期計算を連鎖させることができます。このフューチャーが表す非同期計算が終了すると、`function ` が `context ` オブジェクトのスレッドで呼び出されます。これは、コンティニュエーションを特定のスレッドで呼び出す必要がある場合に役立ちます。例えば:

// somewhere in the main thread
auto future = QtConcurrent::run([] {
    // This will run in a separate thread
    //...
}).then(this, [] {
    // Update UI elements
});

QtConcurrent::run に添付されたコンティニュエーションは UI 要素を更新するため、GUI 以外のスレッドからは呼び出すことができません。そのため、.then() に対してthis をコンテキストとして指定し、メインスレッドで確実に呼び出されるようにしています。

以下の継続も、別のコンテキストや起動ポリシーが指定されていない限り、同じコンテキストから呼び出されます:

auto future = QtConcurrent::run([] {
    //...
}).then(this, [] {
    // Update UI elements
}).then([] {
    // This will also run in the main thread
});

これは、デフォルトでは.then() が前のスレッドと同じスレッドから呼び出されるためです。

ただし、このフューチャーがすでに完了した後に継続が添付された場合、then() を実行するスレッドで、その継続が直ちに呼び出されることに注意してください:

QObject *context /*...*/;
auto future = cachedResultsReady ? QtFuture::makeReadyVoidFuture()
                                : QtConcurrent::run([] { /* compute result */});
auto continuation = future.then(context, [] {
    // Runs in the context's thread
}).then([] {
    // May or may not run in the context's thread
});

上記の例で、cachedResultsReady がtrue であり、readyなフューチャーが返された場合、最初の.then() が、2番目のフューチャーがアタッチされる前に完了してしまう可能性があります。この場合、現在のスレッドで解決されます。したがって、疑わしい場合は、コンテキストを明示的に渡してください。

チェーンが完了する前にcontext が破棄されると、フューチャーはキャンセルされます。これは、context がもはや有効でなくなった時点で、キャンセルハンドラが呼び出される可能性があることを意味します。これを防ぐには、context をQPointer としてキャプチャしてください:

QObject *context /*...*/;
QFuture<Result> future /*...*/;
auto continuation = future.then(context, [context](Result result) {
                            // ...
                        }).onCanceled([context = QPointer(context)] {
                            if (!context)
                                return;  // context was destroyed already
                            // handle cancellation
                        });

コンテキストオブジェクトが破棄されると、直ちにキャンセルが行われます。チェーン内のそれ以前のフューチャーはキャンセルされず、完了するまで実行され続けます。

注: このメソッドを呼び出す際は 、チェーンの設定中にcontext が存続していることが保証されている必要があります。

これはオーバーロードされた関数です。

この関数は Qt 6.1 で導入されました。

onFailed() およびonCanceled()も参照してください 。

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QThreadPool *pool, Function &&function)

このフューチャーに継続を紐付け、必要に応じて複数の非同期計算を連鎖させることができます。このフューチャーが表す非同期計算が完了すると、function がpool に対してスケジューリングされます。

これはオーバーロードされた関数です。

この関数は Qt 6.0 で導入されました。

onFailed() およびonCanceled()も参照してください 。

[since 6.0] template <typename Function> QFuture<QFuture<T>::ResultType<Function>> QFuture::then(QtFuture::Launch policy, Function &&function)

このフューチャーに継続を関連付け、複数の非同期計算を連鎖させることができます。このフューチャーが表す非同期計算が終了すると、指定された起動policy に従ってfunction が呼び出されます。継続の結果を表す新しいQFuture が返されます。

policy に応じて、継続は、このフューチャーと同じスレッドで呼び出されるか、新しいスレッドで呼び出されるか、あるいはこのフューチャーの起動ポリシーとスレッドプールを継承します。起動ポリシーが指定されていない場合(callable のみを受け取るオーバーロードを参照)、Sync ポリシーが使用されます。

次の例では、両方の継続が新しいスレッド(ただし同じスレッド内)で呼び出されます。

QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... }).then([](int res2){ ... });

次の例では、両方の継続が、同じスレッドプールを使用する新しいスレッドで呼び出されます。

QFuture<int> future = ...;
future.then(QtFuture::Launch::Async, [](int res){ ... })
      .then(QtFuture::Launch::Inherit, [](int res2){ ... });

function の詳細については、他のオーバーロードのドキュメントを参照してください。

これはオーバーロードされた関数です。

この関数は Qt 6.0 で導入されました。

onFailed() およびonCanceled()も参照してください 。

[since 6.0] void QFuture::toggleSuspended()

非同期計算のサスペンド状態を切り替えます。つまり、計算が現在サスペンド中または一時停止中の場合、この関数を呼び出すと計算が再開され、計算が実行中の場合はサスペンド状態になります。これは、setSuspended (!(isSuspending() ||isSuspended()))を呼び出すための便利なメソッドです。

この関数は Qt 6.0 で導入されました。

setSuspended()、suspend()、およびresume()も参照してください 。

[since 6.4] template <typename U> QFuture<U> QFuture::unwrap()

この `QFuture<T>` から内部のフューチャーを展開します。ここで、T は `QFuture<U>` 型のフューチャーであり、つまりこのフューチャーの型は `QFuture<QFuture<U>>` となります。例えば:

QFuture<QFuture<int>> outerFuture /*...*/;
QFuture<int> unwrappedFuture = outerFuture.unwrap();

unwrappedFuture outerFuture 内にネストされた内部フューチャーが履行されるとすぐに、同じ結果または例外とともに、内部フューチャーの完了を報告したのと同じスレッドで履行されます。内部フューチャーがキャンセルされた場合、 も同様にキャンセルされます。unwrappedFuture

これは、複数の計算をチェーンでつなぐ際、そのうちの1つが結果型としてQFuture を返す場合に特に有用です。例えば、URLから複数の画像をダウンロードし、それらの画像をリサイズして、QtConcurrent::mappedReduced() を使用して1つの画像に集約したいとします。次のようなコードを書くことができます:

auto downloadImages = [] (const QUrl &url) {
    QList<QImage> images;
    //...
    return images;
};

auto processImages = [scale, reduceImages](const QList<QImage> &images) {
    return QtConcurrent::mappedReduced(images, scale, reduceImages);
};

auto show = [](const QImage &image) { /*...*/ };

auto future = QtConcurrent::run(downloadImages, url)
            .then(processImages)
            .unwrap()
            .then(show);

ここで、QtConcurrent::mappedReduced() はQFuture<QImage> を返すため、.then(processImages) はQFuture<QFuture<QImage>> を返します。show() はQImage を引数として取るため、.then(processImages) の結果を直接渡すことはできません。.unwrap() を呼び出す必要があります。これにより、内部のfutureの結果が準備でき次第取得され、次の継続に渡されます。

ネストが複数ある場合、.unwrap() は最も内側のレベルまで掘り下げます:

QFuture<QFuture<QFuture<int>>> outerFuture;
QFuture<int> unwrappedFuture = outerFuture.unwrap();

この関数は Qt 6.4 で導入されました。

void QFuture::waitForFinished()

非同期計算(cancel() で実行された計算を含む)が完了するまで、つまりisFinished() がtrue を返すまで待機します。

QFuture<T> &QFuture::operator=(const QFuture<T> &other)

このフューチャーにother を割り当て、このフューチャーへの参照を返します。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.