Qt Concurrent 的变化

Qt 6 是努力使框架更高效,且更易于使用的结果。

为兼容每个发行的所有公共 API,我们试着维护二进制和源代码。但是,为使 Qt 成为更优框架,一些改变是不可避免的。

在此话题中,我们汇总了那些 Qt Concurrent 变化,并提供处理它们的指导。

QtConcurrent::run()

QtConcurrent::run() has been improved to work with a variable number of arguments, so the signatures are changed to:

// run
template <typename T>
QFuture<T> run(Function &&f, Args &&...args)
// run with a QThreadPool argument
template <typename T>
QFuture<T> run(QThreadPool *pool, Function &&f, Args &&...args)
					

As a side effect, if f is a pointer to a member function, the first argument of args should be the object for which that member is defined (or a reference, or a pointer to it). So instead of writing:

QImage image = ...;
QFuture<void> future = QtConcurrent::run(&image, &QImage::invertPixels, QImage::InvertRgba);
					

You have to write:

QFuture<void> future = QtConcurrent::run(&QImage::invertPixels, &image, QImage::InvertRgba);
					

Another side effect is that QtConcurrent::run() will not work with overloaded functions anymore. For example, the code below won't compile:

void foo(int arg);
void foo(int arg1, int arg2);
...
QFuture<void> future = QtConcurrent::run(foo, 42);
					

The easiest workaround is to call the overloaded function through lambda:

QFuture<void> future = QtConcurrent::run([] { foo(42); });
					

Or you can tell the compiler which overload to choose by using a static_cast :

QFuture<void> future = QtConcurrent::run(static_cast<void(*)(int)>(foo), 42);
					

Or qOverload :

QFuture<void> future = QtConcurrent::run(qOverload<int>(foo), 42);
					

Other methods of QtConcurrent have no behavioral changes and do not introduce source compatibility breaks.