1

我正在使用 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 函数中清除并将结果保存在适当的容器中。

我做了一些研究,找到了这个源文件,它引用了这些代码片段。在那里,地图函子的模板如下:

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

这确实适用于QtConcurrentmapmapped功能,但是我尝试制作具有相同模式的 reduce 函子再次导致这些错误:

..\qt_photoaud\task.cpp(230) : 错误 C2893: 无法专门化函数模板 'QFuture::ResultType> QtConcurrent::mappedReduced(Iterator,Iterator,MapFunctor,ReduceFunctor,QtConcurrent::ReduceOptions)' 使用以下模板参数: 'QList::iterator' with [ T=QString ] 'ProcMapWrapper' 'ProcReduceWrapper' ..\qt_photoaud\task.cpp(230) : 错误 C2783: 'QFuture QtConcurrent::mappedReduced(Iterator,Iterator,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> QtConcurrent::mappedReduced(const Sequence &,MapFunctor,ReduceFunctor,QtConcurrent::ReduceOptions)' 使用以下模板参数:'QList::iterator' with [ T=QString ] 'QList::iterator' with [ T=QString ] 'ProcMapWrapper' ..\qt_photoaud\task.cpp(230) : error C2783: 'QFuture QtConcurrent::mappedReduced(const Sequence &,MapFunctor,ReduceFunctor,QtConcurrent::ReduceOptions )' : 无法推断 'ResultType' c:\qt\4.8.4\include\qtcore../../src/corelib/concurrent/qtconcurrentmap.h(125) 的模板参数:参见 'QtConcurrent:: 的声明映射减少'

reduce 函子真的被定义和/或认可了吗?QtPrivate::ReduceResultType::ResultType 是如何工作的?它需要什么?

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

4

1 回答 1

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)->-(reduce)-> 一样,map functor 将 result_type 定义为 stage1Data,而 reduce functor 根本没有定义任何 result_type。未来观察者将其类型定义为 reduce 结果(即,其第一个输出参数的类型) - 在我的例子中, int - 以及 mappedReduced 的模板参数是明确定义的。

于 2013-07-02T06:13:49.670 回答