Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 合并并发调用_C++_Qt_Promise_Qt5 - Fatal编程技术网

C++ 合并并发调用

C++ 合并并发调用,c++,qt,promise,qt5,C++,Qt,Promise,Qt5,我有三个方法,它们都返回一个字符串,我想使用QtConcurrent运行它们,并将它们返回到一个列表或类似的东西中QtConcurrent::mapped非常理想,因为它返回一个迭代器,但我一次只能运行一个方法。 在JavaScript中有promise.all([method\u a,method\u b,method\u c]),它会自动将它们的返回合并到一个结果(迭代器)中。 如何在Qt中实现这一点?您正在寻找的方法是: QList QFuture::results()const 返回将来

我有三个方法,它们都返回一个字符串,我想使用
QtConcurrent
运行它们,并将它们返回到一个列表或类似的东西中
QtConcurrent::mapped
非常理想,因为它返回一个迭代器,但我一次只能运行一个方法。 在JavaScript中有
promise.all([method\u a,method\u b,method\u c])
,它会自动将它们的返回合并到一个结果(迭代器)中。
如何在Qt中实现这一点?

您正在寻找的方法是:

QList QFuture::results()const

返回将来的所有结果。如果结果不正确 此功能立即可用,将阻塞并等待它们恢复 变得可用

从Qt自身扩展:

QImage缩放(常量QImage和图像)
{
返回图像。缩放(100100);
}
QList图像=。。。;
QList thumbnails=QtConcurrent::mapped(图像,缩放).results();

因为没有内置的方法来实现这一点,所以您可以自己设计一个类来保持未来,并在所有任务完成后返回结果集合。这里唯一的限制是由于c++的强类型特性:由
QtConcurrent::run
返回的每个future都保存被调用的函数结果,其类型在编译时作为
QFuture
模板参数给出。如果被调用函数的返回类型彼此不同怎么办?在我提供的示例中,它们都返回相同的类型,但我认为可以使用
QVariant
来表示这一意思,并且可以忽略它

在承诺中。h:

并将此回调传递给promise
,然后

void callback(QVector<int> results)
{
    qDebug() << results;
}

以防万一,有人想知道为什么我要加入三个类,而不是直接让
Promise
extend
QObject
,并实现
finished
插槽本身:Qt不让我这么做。当“代码”> QyObjult< /Cuff>宏被添加到类模板时,将显示一个显式编译器错误:QSobject不支持的模板类。

< P>我知道是一个C++库,它将调用转换成QWORD类型,并将它像JavaScript中的一个承诺对象一样使用(将多个不同类型的期货组合成一个单一的未来对象)。不幸的是,我从来没有用过它!但是关于这个引用Qt Blog有很多细节

因为您有几个方法要调用,所以您可以将它们作为一个functor序列作为第一个参数传递给
QtConcurrent::mapped
。映射函子将是一个
apply
函子,它接受一个表示方法调用的函子并返回调用它的结果

首先,让我们来上课:

// https://github.com/KubaO/stackoverflown/tree/master/questions/concurrent-combine-49802153
#include <QtConcurrent>
#include <functional>
#include <initializer_list>
#include <type_traits>

class Cls {
public:
   QString method1() const { return QStringLiteral("10"); }
   QString method2() const { return QStringLiteral("20"); }
   QString method3() const { return QStringLiteral("30"); }
};
让我们方便地从要调用的函子序列类型中创建这样的应用程序:

template <class Sequence, class A = apply_t<typename std::decay_t<Sequence>::value_type>>
A make_apply(Sequence &&) { return {}; }
然后,问题变得相当简单。首先,我们创建一个将被调用的绑定方法的向量。然后,我们将要调用的方法以及对其进行操作的应用程序传递给
QtConcurrent::mapped
results()
按顺序列出了方法调用的所有结果

int main() {
   Cls obj;
   auto const methods = make_vector({
                                 std::bind(&Cls::method1, &obj),
                                 std::bind(&Cls::method2, &obj),
                                 std::bind(&Cls::method3, &obj)
                              });
   QFuture<QString> result =
         QtConcurrent::mapped(methods, make_apply(methods));
   Q_ASSERT((result.results() == QStringList{"10", "20", "30"}));
}
intmain(){
Cls obj;
自动常量方法=生成向量({
std::bind(&Cls::method1和&obj),
std::bind(&Cls::method2和&obj),
std::bind(&Cls::method3和&obj)
});
未来结果=
QtConcurrent::mapped(方法,make_apply(方法));
Q_断言((result.results()==QStringList{10”,“20”,“30}));
}

我们可以使用包装的lambda来提供
QtConcurrent::mapped
所期望的
result\u-type
成员类型,而不是定制
apply\t
类。有关包装lambda的详细信息,请参见。提供了这种包装的示例。

您不明白我的意思,我想同时调用三种方法,假设有
scaled1
scaled2
scaled3
,而不仅仅是
scaled
。然后像javascript中的
promise.all
一样获取所有结果。@MrGisa逐个获取它们并连接。如果返回的是阻塞调用,则使用QVector和append。如果not
QtConcurrent
错误,请使用QThread并在线程中所有3个值都可用时将该值作为合并的单个值发送回。没有任何语法可以将所有返回合并到一个值中,而您可以从Perl或Javascript中了解到这些值。@user3606329当然有一个合并操作,
QFuture
已经通过
results()
方法提供了它!@库巴·奥伯:是的,我知道
QFuture::results()
。OP可能需要一行代码来合并3个QT并发调用的结果,并显示了Javascript中的promise.all方法作为参考?这些函数对象可用于向函数调用添加状态。这句话的含义是什么?@Crawl.W
result\u type
Method
返回的类型。为了在某些情况下使用,函子(可调用对象)需要有
result\u type
type成员,或trait类中的等效类型。
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QList<QFuture<int>> futures = {
        QtConcurrent::run(&f, 1),
        QtConcurrent::run(&f, 2),
        QtConcurrent::run(&f, 3)
    };

    Promise<int> promise(futures);
    promise.then(callback);

    return a.exec();
}
QVector(1, 2, 3)
// https://github.com/KubaO/stackoverflown/tree/master/questions/concurrent-combine-49802153
#include <QtConcurrent>
#include <functional>
#include <initializer_list>
#include <type_traits>

class Cls {
public:
   QString method1() const { return QStringLiteral("10"); }
   QString method2() const { return QStringLiteral("20"); }
   QString method3() const { return QStringLiteral("30"); }
};
template <class Method> struct apply_t {
   using result_type = typename std::result_of_t<Method()>;
   auto operator()(Method method) {
      return method();
   }
};
template <class Sequence, class A = apply_t<typename std::decay_t<Sequence>::value_type>>
A make_apply(Sequence &&) { return {}; }
template <class T> QVector<T> make_vector(std::initializer_list<T> init) {
   return {init};
}
int main() {
   Cls obj;
   auto const methods = make_vector({
                                 std::bind(&Cls::method1, &obj),
                                 std::bind(&Cls::method2, &obj),
                                 std::bind(&Cls::method3, &obj)
                              });
   QFuture<QString> result =
         QtConcurrent::mapped(methods, make_apply(methods));
   Q_ASSERT((result.results() == QStringList{"10", "20", "30"}));
}