为mappedReduce指定reduce functor

时间:2013-06-10 08:43:33

标签: c++ qt concurrency

我正在使用QtConcurrent并行运行某个任务。但是,当我修改为使用mappedReduced而不是map时,我遇到了一个问题。

以下是我使用的代码:

struct ProcMapWrapper {
  ConcurrentProcessTask *instance;
  ProcMapWrapper(ConcurrentProcessTask *w): instance(w) {}
  QString & operator()(const QString& data) {
    return instance->map(data);
  }
  ProcMapWrapper(const ProcMapWrapper & src)
  {
      instance = src.instance;
  }
  typedef QString result_type;
};

struct ProcReduceWrapper {
  ConcurrentProcessTask *instance;
  ProcReduceWrapper(ConcurrentProcessTask *w): instance(w) {}
  void operator()(int &number, const QString &fname) {
    return instance->reduce(number,fname);
  }
  ProcReduceWrapper(const ProcReduceWrapper & src)
  {
      instance = src.instance;
  }
  typedef int result_type;
};

ProcMapWrapper mw(this);
ProcReduceWrapper rw(this);
futureWatcher.setFuture(QtConcurrent::mappedReduced(_files.begin(),_files.end(),mw,rw));

这个想法是使用processOneItem函数从输入字符串生成stage1Data结构,然后在reduce函数中清除并将结果保存在适当的容器中。

我做了一些研究,引导我this source file,指的是these code snippets。在那里,地图仿函数的模板如下:

struct Scaled 
{ 
     Scaled(int size) 
     : m_size(size) { } 

     typedef QImage result_type; 

     QImage operator()(const QImage &image) 
     { 
         return image.scaled(m_size, m_size); 
     } 

     int m_size; 
}; 

 QList<QImage> images = ...; 
 QFuture<QImage> thumbnails = QtConcurrent::mapped(images, Scaled(100));

这确实适用于QtConcurrent的mapmapped函数,但是我尝试使用相同模式制作reduce函子会再次导致这些错误:

  

.. \ qt_photoaud \ task.cpp(230):错误C2893:无法专业化   功能模板   “QFuture ::与resultType&GT;   QtConcurrent :: mappedReduced(迭代器,迭代器,MapFunctor,ReduceFunctor,QtConcurrent :: ReduceOptions)”           使用以下模板参数:           '的QList ::迭代器'           同           [               T = QString的           ]           'ProcMapWrapper'           'ProcReduceWrapper'.. \ qt_photoaud \ task.cpp(230):错误C2783:'QFuture   QtConcurrent :: mappedReduced(迭代器,迭代器,MapFunctor,ReduceFunctor,QtConcurrent :: ReduceOptions)”   :无法推断'ResultType'的模板参数           c:\ qt \ 4.8.4 \ include \ qtcore ../../ src / corelib / concurrent / qtconcurrentmap.h(152):参见'QtConcurrent :: mappedReduced'的声明   .. \ qt_photoaud \ task.cpp(230):错误C2893:无法专门化   功能模板   “QFuture ::与resultType&GT;   QtConcurrent :: mappedReduced(const Sequence   &安培;,MapFunctor,ReduceFunctor,QtConcurrent :: ReduceOptions)”           使用以下模板参数:           '的QList ::迭代器'           同           [               T = QString的           ]           '的QList ::迭代器'           同           [               T = QString的           ]           'procMapWrapper'.. \ qt_photoaud \ task.cpp(230):错误C2783:'QFuture QtConcurrent :: mappedReduced(const Sequence)   &amp;,MapFunctor,ReduceFunctor,QtConcurrent :: ReduceOptions)':不能   推导出'ResultType'的模板参数           c:\ qt \ 4.8.4 \ include \ qtcore ../../ src / corelib / concurrent / qtconcurrentmap.h(125):参见'QtConcurrent :: mappedReduced'的声明

是否真的定义和/或识别了reduce functor? QtPrivate :: ReduceResultType :: ResultType如何工作?它需要什么?

编辑:假设仿函数与boost :: function兼容,我尝试在reduce仿函数中指定first_argument_type,second_argument_type,arg1_type和arg2_type。但这没有任何帮助。

1 个答案:

答案 0 :(得分:2)

这对我有用:

struct concurrentProcessDBMapper
{
    typedef stage1Data result_type;
    stage1Data operator()(QString fname)
    {
        return concurrentProcessDBMap(fname);
    }
};

struct concurrentProcessDBReducer
{
    DatabaseConcurrentProcessTask *instance;
    concurrentProcessDBReducer(DatabaseConcurrentProcessTask *i)
    {
        instance = i;
    }

    void operator()(int & number, const stage1Data in)
    {
        //concurrentProcessDBReduce
        instance->reduce(number,in);
    }
};
...
    QFutureWatcher<int> futureWatcher;

    QList<QString> _filesInWork;

...
futureWatcher.setFuture(
     QtConcurrent::mappedReduced
         <int, QList<QString>, concurrentProcessDBMapper,concurrentProcessDBReducer>
                            (_filesInWork,concurrentProcessDBMapper(),concurrentProcessDBReducer(this)));
...

总结一下,类型转换就像 - (map) - &gt ;-(reduce) - &gt;,map functor将result_type定义为stage1Data,而reduce functor根本没有定义任何result_type。未来的观察者将其类型定义为reduce结果(即,它的第一个out参数的类型) - 在我的例子中,int - 和mappedReduced的模板参数是明确定义的。