我正在使用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的map
和mapped
函数,但是我尝试使用相同模式制作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。但这没有任何帮助。
答案 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的模板参数是明确定义的。