QtFuture 命名空间

包含由QFuture类使用的杂项标识符。更多...

头文件 #include <QFuture>
CMakefind_package(Qt6 REQUIRED COMPONENTS Core)
target_link_libraries(mytarget PRIVATE Qt6::Core)
qmakeQT += core

(自 6.3) structWhenAnyResult

类型

(自 6.0) enum classLaunch { Sync, Async, Inherit }

函数

QFuture<QtFuture::ArgsType<Signal>>connect(Sender *sender, Signal signal)
(自 6.1) QFuture<T>makeExceptionalFuture(const QException &exception)
(自 6.1) QFuture<T>makeExceptionalFuture(std::__exception_ptr::exception_ptr exception)
(自 6.6) QFuture<QtFuture::ContainedType<Container>>makeReadyRangeFuture(Container &&container)
(自 6.6) QFuture<ValueType>makeReadyRangeFuture(std::initializer_list<ValueType> values)
(自 6.6) QFuture<std::decay_t<T>>makeReadyValueFuture(T &&value)
(自 6.6) QFuture<void>makeReadyVoidFuture()
(自 6.3) QFuture<OutputSequence>whenAll(InputIt first, InputIt last)
(自 6.3) QFuture<OutputSequence>whenAll(Futures &&... futures)
(自 6.3) QFuture<QtFuture::WhenAnyResult<T>>whenAny(InputIt first, InputIt last)
(自 6.3) QFuture<std::variant<std::decay_t<Futures>...>>whenAny(Futures &&... futures)

详细说明

类型文档

[since 6.0] enum class QtFuture::Launch

表示运行 QFuture 后续操作的执行策略。

常量描述
QtFuture::Launch::Sync0后续将启动在执行与未来相关的承诺的同一线程上,或者如果已经完成,则将在执行 then() 的线程中立即调用后续。
QtFuture::Launch::Async1后续将在从全局 QThreadPool 中获取的单独线程中启动。
QtFuture::Launch::Inherit2后续将继承其附加的未来的启动策略或线程池。

Sync 被用作默认启动策略。

此枚举是在 Qt 6.0 中引入的。

另请参阅QFuture::then() 和 QThreadPool::globalInstance

函数文档

模板 <typename Sender, typename Signal, typename = QtPrivate::EnableIfInvocable<Sender, Signal>> QFuture<QtFuture::ArgsType<Signal>> QtFuture::connect(Sender *sender, Signal signal)

创建并返回一个 QFuture,当 sender 发射 signal 时将可用。如果 signal 没有参数,返回 QFuture<void>。如果 signal 只接受一个参数,结果 QFuture 将用信号参数的值填充。如果 signal 接受多个参数,结果 QFuture 将用存储信号参数值的 std::tuple 填充。如果 sendersignal 发射之前被销毁,结果 QFuture 将被取消。

例如,假设我们有以下对象

class Object : public QObject
{
    Q_OBJECT
    ...
signals:
    void noArgSignal();
    void singleArgSignal(int value);
    void multipleArgs(int value1, double value2, const QString &value3);
};

我们可以以以下方式将其信号连接到 QFuture 对象

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)

我们还可以将后续链接,以在信号发射时运行

QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) {
    // do something with the value
});

您也可以使用 QtFuture::Launch 策略在新的线程或自定义线程池中启动后续。例如

QtFuture::connect(&object, &Object::singleArgSignal).then(QtFuture::Launch::Async, [](int value) {
    // this will run in a new thread
});

如果 Qt 的信号-槽连接槽调用抛出异常,如果没有在槽中处理,则视为未定义行为。但是通过 QFuture::connect(),您可以在后续中抛出和处理异常

QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) {
    ...
    throw std::exception();
    ...
}).onFailed([](const std::exception &e) {
    // handle the exception
}).onFailed([] {
    // handle other exceptions
});

注意:连接的未来只有在信号第一次发射时才会完全实现。

另请参阅QFutureQFuture::then

[since 6.1] 模板 <typename T = void> QFuture<T> QtFuture::makeExceptionalFuture(const QException &exception)

创建并返回一个已经包含异常 exceptionQFuture

QException e;
auto f = QtFuture::makeExceptionalFuture<int>(e);
...
try {
    f.result(); // throws QException
} catch (QException &) {
    // handle exception here
}

此函数是在 Qt 6.1 中引入的。

另请参阅QFutureQExceptionQtFuture::makeReadyVoidFuture() 和 QtFuture::makeReadyValueFuture

[since 6.1] 模板 <typename T = void> QFuture<T> QtFuture::makeExceptionalFuture(std::__exception_ptr::exception_ptr exception)

这是一个重载函数。

创建并返回一个已经包含异常 exceptionQFuture

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 中引入的。

另请参阅QFutureQExceptionQtFuture::makeReadyVoidFuture() 和 QtFuture::makeReadyValueFuture

[自6.6起] 模板 <typename Container, QtFuture::if_container_with_input_iterators<Container> = true> QFuture<QtFuture::ContainedType<Container>> QtFuture::makeReadyRangeFuture(Container &&container)

这是一个重载函数。

接受一个输入容器 container 并返回一个包含从 container 值初始化的多个结果的 QFuture

注意:此重载仅在 Container 具有输入迭代器时参与重载解析。

const std::vector<int> values{1, 2, 3};
auto f = QtFuture::makeReadyRangeFuture(values);
    ...
const int count = f.resultCount(); // count == 3
const auto results = f.results(); // results == { 1, 2, 3 }

此函数是在 Qt 6.6 中引入的。

另请参阅:QFutureQtFuture::makeReadyVoidFuture()、QtFuture::makeReadyValueFuture() 和 QtFuture::makeExceptionalFuture

[自6.6起] 模板 <typename ValueType> QFuture<ValueType> QtFuture::makeReadyRangeFuture(std::initializer_list<ValueType> values)

这是一个重载函数。

返回一个包含从输入初始化列表 values 初始化的多个结果的 QFuture

auto f = QtFuture::makeReadyRangeFuture({1, 2, 3});
    ...
const int count = f.resultCount(); // count == 3
const auto results = f.results(); // results == { 1, 2, 3 }

此函数是在 Qt 6.6 中引入的。

另请参阅:QFutureQtFuture::makeReadyVoidFuture()、QtFuture::makeReadyValueFuture() 和 QtFuture::makeExceptionalFuture

[自6.6起] 模板 <typename T> QFuture<std::decay_t<T>> QtFuture::makeReadyValueFuture(T &&value)

创建并返回一个已经包含结果 valueQFuture。返回的 QFuture 类型为 std::decay_t<T>,其中 T 不为 void。返回的 QFuture 将已在完成状态。

auto f = QtFuture::makeReadyValueFuture(std::make_unique<int>(42));
...
const int result = *f.takeResult(); // result == 42

此函数是在 Qt 6.6 中引入的。

另请参阅:QFutureQtFuture::makeReadyRangeFuture()、QtFuture::makeReadyVoidFuture() 和 QtFuture::makeExceptionalFuture

[自6.6起] QFuture<void> QtFuture::makeReadyVoidFuture()

创建并返回一个空 QFuture。这种 QFuture 无法存储任何结果。它可以用作查询计算的状态。返回的 QFuture 将已在完成状态。

auto f = QtFuture::makeReadyVoidFuture();
...
const bool started = f.isStarted(); // started == true
const bool running = f.isRunning(); // running == false
const bool finished = f.isFinished(); // finished == true

此函数是在 Qt 6.6 中引入的。

另请参阅:QFutureQFuture::isStarted()、QFuture::isRunning()、QFuture::isFinished()、QtFuture::makeReadyValueFuture()、QtFuture::makeReadyRangeFutureQtFuture::makeExceptionalFuture

[自6.3起] 模板 <typename OutputSequence, typename InputIt> QFuture<OutputSequence> QtFuture::whenAll(InputIt first, InputIt last)

返回一个新的QFuture,当从firstlast的所有future完成时,该future将成功。 firstlast是类型为T的future封装类型序列的迭代器。 OutputSequence是一个包含从firstlast的所有完成future的序列,出现的顺序与输入相同。如果未指定OutputSequence的类型,则将返回包含QFuture<T>QList中的结果future。例如

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());

注意:输出序列必须支持随机访问和resize()操作。

如果first等于last,则此函数返回一个包含空OutputSequence的已准备好QFuture

返回的未来总是在所有指定的future完成后才成功完成。无论这些future中的哪个完成时出错或被取消,都没有关系。您可以在whenAll()返回的未来之后使用.then()来处理已完成的future。

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
            }
        });

注意:如果输入的future在不同的线程上完成,此方法返回的未来将在最后一个future完成的线程中完成。因此,附在whenAll()返回的未来上的延续不能总是假设要在哪个线程上运行。如果您想控制延续要在哪个线程上调用,请使用带参数上下文的.then()的重载。

此函数是在Qt 6.3中引入的。

[since 6.3] 模版 <typename OutputSequence, typename... Futures> QFuture<OutputSequence> QtFuture::whenAll(Futures &&... futures)

返回一个新的QFuture,当所有包装任意类型的futures完成时,该future将成功。OutputSequence是一个完成future的序列。其条目类型为std::variant<Futures...>。对于传递给whenAll()的每个QFuture<T>,在OutputSequence对应位置的条目将是一个包含其完成状态的QFuture<T>std::variant。如果未指定OutputSequence的类型,则结果future将返回在包含std::variant<Futures...>QList中。例如

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);

注意:输出序列应该支持随机访问和resize()操作。

返回的未来总是在所有指定的future完成后才成功完成。无论这些future中的哪个完成时出错或被取消,都没有关系。您可以在whenAll()返回的未来之后使用.then()来处理已完成的future。

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);
            }
            ...
        });

注意:如果输入的future在不同的线程上完成,此方法返回的未来将在最后一个future完成的线程中完成。因此,附在whenAll()返回的未来上的延续不能总是假设要在哪个线程上运行。如果您想控制延续要在哪个线程上调用,请使用带参数上下文的.then()的重载。

此函数是在Qt 6.3中引入的。

[since 6.3] 模版 <typename T, typename InputIt> QFuture<QtFuture::WhenAnyResult<T>> QtFuture::whenAny(InputIt first, InputIt last)

返回一个新的QFuture,该QFuture在任何从firstlast的QFuture完成时都成功。 firstlast是打包类型T的QFuture序列的迭代器。返回的QFuture打包一个类型为QtFuture::WhenAnyResult<T>的值,后者则打包第一个完成的QFuture的索引和本身。如果first等于last,此函数返回一个准备就绪的QFuture,其QtFuture::WhenAnyResult中的index字段为-1,并且为future字段构建一个默认的QFuture<T>。请注意,默认构建的QFuture是在已取消状态的已完成的QFuture。

返回的QFuture总是在指定的一个QFuture完成后的第一次成功完成。无论第一个QFuture是成功完成还是有错误或被取消,都无关紧要。你可以在whenAny()返回的QFuture成功后使用.then()来处理结果

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;
            // ...
        });

注意: 如果输入的QFuture在不同的线程中完成,此方法返回的QFuture将在第一个QFuture完成的线程中完成。因此,附加到whenAny()返回的QFuture的后续操作不能总是假设它们将在哪个线程上运行。如果你想控制后续操作在哪个线程上调用,请使用带上下文对象的.then()的重载。

此函数是在Qt 6.3中引入的。

另请参阅 QtFuture::WhenAnyResult

[自6.3以来] 模板 <typename... Futures> QFuture<std::variant<std::decay_t<Futures>...>> QtFuture::whenAny(Futures &&... futures)

返回一个新的QFuture,当任何futures完成时都成功。 futures可以打包任意类型。返回的QFuture打包一个类型为std::variant<Futures...>的值,后者则打包从futures中第一个完成的QFuture。你可以使用std::variant::index()来确定在futures序列中哪个QFuture首先完成。

返回的QFuture总是在指定的一个QFuture完成后的第一次成功完成。无论第一个QFuture是成功完成还是有错误或被取消,都无关紧要。你可以在whenAny()返回的QFuture成功后使用.then()来处理结果

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);
    ...
});

注意: 如果输入的QFuture在不同的线程中完成,此方法返回的QFuture将在第一个QFuture完成的线程中完成。因此,附加到whenAny()返回的QFuture的后续操作不能总是假设它们将在哪个线程上运行。如果你想控制后续操作在哪个线程上调用,请使用带上下文对象的.then()的重载。

此函数是在Qt 6.3中引入的。

© 2024 Qt公司有限公司。本文件包含的文档贡献均为各自所有者的版权。提供的文档受GNU自由文档许可证版本1.3的条款约束,由自由软件基金会发布。Qt及其相关标志是芬兰及全世界其他国家的Qt公司所有和/或注册商标。所有其他商标均为其各自所有者的财产。