头: | #include < QFuture > |
CMake: |
find_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
struct | WhenAnyResult |
enum class | Launch { Sync, Async, Inherit } |
QFuture<ArgsType<Signal>> | connect (Sender * sender , Signal signal ) |
QFuture<T> | makeExceptionalFuture (const QException & exception ) |
QFuture<T> | makeExceptionalFuture (std::exception_ptr exception ) |
QFuture<std::decay_t<T>> | makeReadyFuture (T && value ) |
QFuture<void> | makeReadyFuture () |
QFuture<T> | makeReadyFuture (const QList<T> & 值 ) |
QFuture<OutputSequence> | whenAll (InputIt first , InputIt last ) |
QFuture<OutputSequence> | whenAll (Futures &&... futures ) |
QFuture<QtFuture::WhenAnyResult<T>> | whenAny (InputIt first , InputIt last ) |
QFuture<std::variant<std::decay_t<Futures>...>> | whenAny (Futures &&... futures ) |
QtFuture::WhenAnyResult is used to represent the result of QtFuture::whenAny (). 更多...
[since 6.0]
enum class QtFuture::
Launch
Represents execution policies for running a QFuture continuation.
常量 | 值 | 描述 |
---|---|---|
QtFuture::Launch::Sync
|
0
|
The continuation will be launched in the same thread that fulfills the promise associated with the future to which the continuation was attached, or if it has already finished, the continuation will be invoked immediately, in the thread that executes
then()
.
|
QtFuture::Launch::Async
|
1
|
The continuation will be launched in a separate thread taken from the global QThreadPool . |
QtFuture::Launch::Inherit
|
2
|
The continuation will inherit the launch policy or thread pool of the future to which it is attached. |
Sync
is used as a default launch policy.
该枚举在 Qt 6.0 引入 (或被修改)。
另请参阅 QFuture::then () 和 QThreadPool::globalInstance ().
创建并返回 QFuture which will become available when the sender 发射 signal 。若 signal takes no arguments, a QFuture <void> is returned. If the signal takes a single argument, the resulted QFuture will be filled with the signal's argument value. If the signal takes multiple arguments, the resulted QFuture is filled with std::tuple storing the values of signal's arguments. If the sender is destroyed before the signal is emitted, the resulted QFuture will be canceled.
For example, let's say we have the following object:
class Object : public QObject { Q_OBJECT ... signals: void noArgSignal(); void singleArgSignal(int value); void multipleArgs(int value1, double value2, const QString &value3); };
We can connect its signals to QFuture objects in the following way:
Object object; QFuture<void> voidFuture = QtFuture::connect(&object, &Object::noArgSignal); QFuture<int> intFuture = QtFuture::connect(&object, &Object::singleArgSignal); using Args = std::tuple<int, double, QString>; QFuture<Args> tupleFuture = QtFuture::connect(&object, &Object::multipleArgs)
We can also chain continuations to be run when a signal is emitted:
QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) { // do something with the value });
You can also start the continuation in a new thread or a custom thread pool using QtFuture::Launch policies. For example:
QtFuture::connect(&object, &Object::singleArgSignal).then(QtFuture::Launch::Async, [](int value) { // this will run in a new thread });
Throwing an exception from a slot invoked by Qt's signal-slot connection is considered to be an undefined behavior, if it is not handled within the slot. But with QFuture::connect(), you can throw and handle exceptions from the continuations:
QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) { ... throw std::exception(); ... }).onFailed([](const std::exception &e) { // handle the exception }).onFailed([] { // handle other exceptions });
注意: The connected future will be fulfilled only once, when the signal is emitted for the first time.
另请参阅 QFuture and QFuture::then ().
[since 6.1]
template <typename T>
QFuture
<
T
> QtFuture::
makeExceptionalFuture
(const
QException
&
exception
)
创建并返回 QFuture which already has an exception exception .
QException e; auto f = QtFuture::makeExceptionalFuture<int>(e); ... try { f.result(); // throws QException } catch (QException &) { // handle exception here }
该函数在 Qt 6.1 引入。
另请参阅 QFuture , QException ,和 QtFuture::makeReadyFuture ().
[since 6.1]
template <typename T>
QFuture
<
T
> QtFuture::
makeExceptionalFuture
(
std::exception_ptr
exception
)
这是重载函数。
创建并返回 QFuture which already has an exception exception .
struct TestException { }; ... auto exception = std::make_exception_ptr(TestException()); auto f = QtFuture::makeExceptionalFuture<int>(exception); ... try { f.result(); // throws TestException } catch (TestException &) { // handle exception here }
该函数在 Qt 6.1 引入。
另请参阅 QFuture , QException ,和 QtFuture::makeReadyFuture ().
[since 6.1]
template <typename T, typename>
QFuture
<
std::decay_t
<
T
>> QtFuture::
makeReadyFuture
(
T
&&
value
)
这是重载函数。
创建并返回 QFuture which already has a result value . The returned QFuture has a type of std::decay_t<T>, where T is not void.
auto f = QtFuture::makeReadyFuture(std::make_unique<int>(42)); ... const int result = *f.takeResult(); // result == 42
该函数在 Qt 6.1 引入。
另请参阅 QFuture and QtFuture::makeExceptionalFuture ().
[since 6.1]
QFuture
<
void
> QtFuture::
makeReadyFuture
()
这是重载函数。
Creates and returns a void QFuture . Such QFuture can't store any result. One can use it to query the state of the computation. The returned QFuture will always be in the finished state.
auto f = QtFuture::makeReadyFuture(); ... const bool started = f.isStarted(); // started == true const bool running = f.isRunning(); // running == false const bool finished = f.isFinished(); // finished == true
该函数在 Qt 6.1 引入。
另请参阅 QFuture , QFuture::isStarted (), QFuture::isRunning (), QFuture::isFinished (),和 QtFuture::makeExceptionalFuture ().
[since 6.1]
template <typename T>
QFuture
<
T
> QtFuture::
makeReadyFuture
(const
QList
<
T
> &
值
)
这是重载函数。
创建并返回 QFuture which already has multiple results set from values .
const QList<int> values { 1, 2, 3 }; auto f = QtFuture::makeReadyFuture(values); ... const int count = f.resultCount(); // count == 3 const auto results = f.results(); // results == { 1, 2, 3 }
该函数在 Qt 6.1 引入。
另请参阅 QFuture and QtFuture::makeExceptionalFuture ().
[since 6.3]
template <typename OutputSequence, typename InputIt>
QFuture
<
OutputSequence
> QtFuture::
whenAll
(
InputIt
first
,
InputIt
last
)
返回新的
QFuture
that succeeds when all futures from
first
to
last
complete.
first
and
last
are iterators to a sequence of futures packaging type
T
.
OutputSequence
is a sequence containing all completed futures from
first
to
last
, appearing in the same order as in the input. If the type of
OutputSequence
is not specified, the resulting futures will be returned in a
QList
of
QFuture<T>
。例如:
QList<QFuture<int>> inputFutures {...}; // whenAll has type QFuture<QList<QFuture<int>>> auto whenAll = QtFuture::whenAll(inputFutures.begin(), inputFutures.end()); // whenAllVector has type QFuture<std::vector<QFuture<int>>> auto whenAllVector = QtFuture::whenAll<std::vector<QFuture<int>>>(inputFutures.begin(), inputFutures.end());
注意:
The output sequence must support random access and the
resize()
操作。
若
第一
等于
last
, this function returns a ready
QFuture
that contains an empty
OutputSequence
.
The returned future always completes successfully after all the specified futures complete. It doesn't matter if any of these futures completes with error or is canceled. You can use
.then()
to process the completed futures after the future returned by
whenAll()
succeeds:
QList<QFuture<int>> inputFutures {...}; QtFuture::whenAll(inputFutures.begin(), inputFutures.end()) .then([](const QList<QFuture<int>> &results) { for (auto future : results) { if (future.isCanceled()) // handle the cancellation (possibly due to an exception) else // do something with the result } });
注意:
If the input futures complete on different threads, the future returned by this method will complete in the thread that the last future completes in. Therefore, the continuations attached to the future returned by
whenAll()
cannot always make assumptions about which thread they will be run on. Use the overload of
.then()
that takes a context object if you want to control which thread the continuations are invoked on.
该函数在 Qt 6.3 引入。
[since 6.3]
template <typename OutputSequence, typename Futures>
QFuture
<
OutputSequence
> QtFuture::
whenAll
(
未来
&&...
futures
)
返回新的
QFuture
that succeeds when all
futures
packaging arbitrary types complete.
OutputSequence
is a sequence of completed futures. The type of its entries is
std::variant<Futures...>
. For each
QFuture<T>
passed to
whenAll()
, the entry at the corresponding position in
OutputSequence
will be a
std::variant
holding that
QFuture<T>
, in its completed state. If the type of
OutputSequence
is not specified, the resulting futures will be returned in a
QList
of
std::variant<Futures...>
。例如:
QFuture<int> intFuture = ...; QFuture<QString> stringFuture = ...; QFuture<void> voidFuture = ...; using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>; // whenAll has type QFuture<QList<FuturesVariant>> auto whenAll = QtFuture::whenAll(intFuture, stringFuture, voidFuture); // whenAllVector has type QFuture<std::vector<FuturesVariant>> auto whenAllVector = QtFuture::whenAll<std::vector<FuturesVariant>>(intFuture, stringFuture, voidFuture);
注意:
The output sequence should support random access and the
resize()
操作。
The returned future always completes successfully after all the specified futures complete. It doesn't matter if any of these futures completes with error or is canceled. You can use
.then()
to process the completed futures after the future returned by
whenAll()
succeeds:
QFuture<int> intFuture = ...; QFuture<QString> stringFuture = ...; QFuture<void> voidFuture = ...; using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>; QtFuture::whenAll(intFuture, stringFuture, voidFuture) .then([](const QList<FuturesVariant> &results) { ... for (auto result : results) { // assuming handleResult() is overloaded based on the QFuture type std::visit([](auto &&future) { handleResult(future); }, result); } ... });
注意:
If the input futures complete on different threads, the future returned by this method will complete in the thread that the last future completes in. Therefore, the continuations attached to the future returned by
whenAll()
cannot always make assumptions about which thread they will be run on. Use the overload of
.then()
that takes a context object if you want to control which thread the continuations are invoked on.
该函数在 Qt 6.3 引入。
[since 6.3]
template <typename T, typename InputIt>
QFuture
<
QtFuture::WhenAnyResult
<
T
>> QtFuture::
whenAny
(
InputIt
first
,
InputIt
last
)
返回新的
QFuture
that succeeds when any of the futures from
first
to
last
completes.
first
and
last
are iterators to a sequence of futures packaging type
T
. The returned future packages a value of type
QtFuture::WhenAnyResult<T>
which in turn packages the index of the first completed
QFuture
和
QFuture
itself. If
first
等于
last
, this function returns a ready
QFuture
that has
-1
为
index
field in the
QtFuture::WhenAnyResult
struct and a default-constructed
QFuture<T>
为
future
field. Note that a default-constructed
QFuture
is a completed future in a cancelled state.
The returned future always completes successfully after the first future from the specified futures completes. It doesn't matter if the first future completes with error or is canceled. You can use
.then()
to process the result after the future returned by
whenAny()
succeeds:
QList<QFuture<int>> inputFutures = ...; QtFuture::whenAny(inputFutures.begin(), inputFutures.end()) .then([](const QtFuture::WhenAnyResult<int> &result) { qsizetype index = result.index; QFuture<int> future = result.future; // ... });
注意:
If the input futures complete on different threads, the future returned by this method will complete in the thread that the first future completes in. Therefore, the continuations attached to the future returned by
whenAny()
cannot always make assumptions about which thread they will be run on. Use the overload of
.then()
that takes a context object if you want to control which thread the continuations are invoked on.
该函数在 Qt 6.3 引入。
另请参阅 QtFuture::WhenAnyResult .
[since 6.3]
template <typename Futures>
QFuture
<
std::variant
<
std::decay_t
<
未来
>...>> QtFuture::
whenAny
(
未来
&&...
futures
)
返回新的
QFuture
that succeeds when any of the
futures
completes.
futures
can package arbitrary types. The returned future packages the value of type
std::variant<Futures...>
which in turn packages the first completed
QFuture
from
futures
。可以使用
std::variant::index()
to find out the index of the future in the sequence of
futures
that finished first.
The returned future always completes successfully after the first future from the specified futures completes. It doesn't matter if the first future completes with error or is canceled. You can use
.then()
to process the result after the future returned by
whenAny()
succeeds:
QFuture<int> intFuture = ...; QFuture<QString> stringFuture = ...; QFuture<void> voidFuture = ...; using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>; QtFuture::whenAny(intFuture, stringFuture, voidFuture).then([](const FuturesVariant &result) { ... // assuming handleResult() is overloaded based on the QFuture type std::visit([](auto &&future) { handleResult(future); }, result); ... });
注意:
If the input futures complete on different threads, the future returned by this method will complete in the thread that the first future completes in. Therefore, the continuations attached to the future returned by
whenAny()
cannot always make assumptions about which thread they will be run on. Use the overload of
.then()
that takes a context object if you want to control which thread the continuations are invoked on.
该函数在 Qt 6.3 引入。