首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtConcurrent blockingMappedReduced错误

QtConcurrent blockingMappedReduced错误
EN

Stack Overflow用户
提问于 2011-11-01 07:43:36
回答 2查看 1.8K关注 0票数 1

这是我第一次尝试使用QtConcurrent::blockingMappedReduced,我无法在MSVC2010Express(带有Qt4.7.1源代码)中构建它。

我已经创建了一个与我的实际代码类似的小示例,并且它具有相同的问题:

代码语言:javascript
复制
// Here's the general outline:
// 1. create a list of random numbers
// 2. pass the list to blockingMappedReduced
// 3. the map function calculates the sine of the given random number
// 4. the reduce function finds the random number with the maximum sine value

// Here's the implementation:

#include "stdafx.h"
#include <qlist.h>
#include <qtconcurrentmap.h>

// My class for the map/reduce functions
class myClass
{
private:

    // Nested class to hold the intermediate results from the map function
    // I think I need this because the reduce function needs more from the map function than a single return value
    class Temp
    {
    public:

        // For example, let's pass these two member variables from the map function to the reduce function
        int randomInput;
        double resultingOutput;

        // The Temp constructor
        Temp::Temp(double randomInput, double resultingOutput)
        {
            this->randomInput = randomInput;
            this->resultingOutput = resultingOutput;
        }
    };

public:

    // For example, these myClass members will hold the final result from the reduce function
    double maximumOutput;
    double maximumInput;

    // The myClass constructor
    myClass::myClass()
    {
        this->maximumOutput = -1;
    }

    // The map function
    const Temp mapFunction(const double& randomInput)
    {
        // For example, let's calculate the sine of the given random number
        double resultingOutput = sin(randomInput);

        // Construct the temporary structure to pass multiple values to the reduce function
        const Temp temp(randomInput, resultingOutput);
        return(temp);
    }

    // The reduce function
    void reduceFunction(double& maxInput, const Temp& temp)
    {
        // For example, let's find the maximum computed sine value
        if (temp.resultingOutput > this->maximumOutput)
        {
            this->maximumOutput = temp.resultingOutput;
            this->maximumInput = temp.randomInput;
        }

        maxInput = this->maximumInput;
    }
};

// Main function
void main(int argc, _TCHAR* argv[])
{
    // Build a list of random numbers
    QList<int> aList;
    for (int count = 8; count > 0; --count)
    {
        aList.append(rand());
    }

    // Invoke the parallel map/reduce function
    myClass myClassInstance;
    double theAnswer = QtConcurrent::blockingMappedReduced(aList, &myClass::mapFunction, &myClass::reduceFunction);
}

编译器会报告最后一行调用blockingMappedReduced的地方。

代码语言:javascript
复制
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'D QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__thiscall C::* )(void) const,U (__thiscall D::* )(V),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(659) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'C QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__cdecl *)(U),V (__thiscall C::* )(W),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(643) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'V QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__thiscall C::* )(void) const,U (__cdecl *)(V &,W),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(627) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'W QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__cdecl *)(U),V (__cdecl *)(W &,X),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(611) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'ResultType QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__thiscall C::* )(void) const,ReduceFunctor,QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(595) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'ResultType QtConcurrent::blockingMappedReduced(Iterator,Iterator,T (__cdecl *)(U),ReduceFunctor,QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(579) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'C QtConcurrent::blockingMappedReduced(Iterator,Iterator,MapFunctor,T (__thiscall C::* )(U),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(563) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'U QtConcurrent::blockingMappedReduced(Iterator,Iterator,MapFunctor,T (__cdecl *)(U &,V),QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(547) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2780: 'ResultType QtConcurrent::blockingMappedReduced(Iterator,Iterator,MapFunctor,ReduceFunctor,QtConcurrent::ReduceOptions)' : expects 5 arguments - 3 provided
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(536) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'D QtConcurrent::blockingMappedReduced(const Sequence &,T (__thiscall C::* )(void) const,U (__thiscall D::* )(V),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__thiscall C::* )(void) const' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(522) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'C QtConcurrent::blockingMappedReduced(const Sequence &,T (__cdecl *)(U),V (__thiscall C::* )(W),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__cdecl *)(U)' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(508) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'V QtConcurrent::blockingMappedReduced(const Sequence &,T (__thiscall C::* )(void) const,U (__cdecl *)(V &,W),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__thiscall C::* )(void) const' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(494) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'W QtConcurrent::blockingMappedReduced(const Sequence &,T (__cdecl *)(U),V (__cdecl *)(W &,X),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__cdecl *)(U)' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(480) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'ResultType QtConcurrent::blockingMappedReduced(const Sequence &,T (__thiscall C::* )(void) const,ReduceFunctor,QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__thiscall C::* )(void) const' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(466) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'ResultType QtConcurrent::blockingMappedReduced(const Sequence &,T (__cdecl *)(U),ReduceFunctor,QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__cdecl *)(U)' from 'const myClass::Temp (__thiscall myClass::* )(const double &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(452) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'C QtConcurrent::blockingMappedReduced(const Sequence &,MapFunctor,T (__thiscall C::* )(U),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__thiscall C::* )(U)' from 'void (__thiscall myClass::* )(double &,const myClass::Temp &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(438) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2784: 'U QtConcurrent::blockingMappedReduced(const Sequence &,MapFunctor,T (__cdecl *)(U &,V),QtConcurrent::ReduceOptions)' : could not deduce template argument for 'T (__cdecl *)(U &,V)' from 'void (__thiscall myClass::* )(double &,const myClass::Temp &)'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(424) : see declaration of 'QtConcurrent::blockingMappedReduced'
c:\gwa\tmp\stackoverflow\stackoverflow\stackoverflow.cpp(77): error C2783: 'ResultType QtConcurrent::blockingMappedReduced(const Sequence &,MapFunctor,ReduceFunctor,QtConcurrent::ReduceOptions)' : could not deduce template argument for 'ResultType'
          c:\gwa\third_party\qt\qt-4.7.1\src\corelib\concurrent\qtconcurrentmap.h(414) : see declaration of 'QtConcurrent::blockingMappedReduced'

来自在线QT文档(http://doc.qt.nokia.com/4.7-snapshot/qtconcurrentmap.html#blockingMappedReduced)的原型如下:

代码语言:javascript
复制
T  blockingMappedReduced ( const Sequence & sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce ) 

恐怕我没有调试这方面的专业知识。任何帮助都将不胜感激。同样,由于我的C++技能不是专家,为了让我理解它,帮助必须是明确的(即实际的代码片段,而不是假设比我拥有更多知识的东西,比如“你的参数必须是一个常量引用”)。

提前感谢您的帮助。

EN

回答 2

Stack Overflow用户

发布于 2011-11-01 09:29:45

您的代码有一些与QtConcurrent无关的一般性问题需要修补。首先,你不应该限定构造函数,而不是:

代码语言:javascript
复制
    // The Temp constructor
    Temp::Temp(double randomInput, double resultingOutput)

你应该简单地写:

代码语言:javascript
复制
    // The Temp constructor
    Temp(double randomInput, double resultingOutput)

myClass也是如此。此外,main的函数签名应该始终返回一个返回值,尽管在C99和C++中,如果您想返回0,可以省略int语句。(然而,我总是明确地将return 0作为个人偏好的问题。)

What should main() return in C and C++?

至于你的QtConcurrent问题,有几个。首先,您的QList是整数类型,文档指出序列中的类型应该与映射函数的第一个参数匹配(其中有一个双精度型)。因此,QList需要更改为双精度,否则您的映射函数需要接受int。

您遇到的另一个问题是,您试图将指向成员函数的指针传递到只需要普通函数的槽中:

代码语言:javascript
复制
    // Invoke the parallel map/reduce function
    myClass myClassInstance;
    double theAnswer = QtConcurrent::blockingMappedReduced(aList,
        &myClass::mapFunction, &myClass::reduceFunction);

请注意,除了声明之外,没有提到myClassInstance。在一般的case...working中,这并不像更改调用来使用&myClassInstance::mapFunction, &myClassInstance::reduceFunction那么容易。环顾四周的C++,你会发现没有一种通常可行的方法可以让对象适合函数调用的任何位置,即使它们被设计成像函数一样可调用:

Help with boost bind/functions

幸运的是,QtConcurrent不会把你逼入绝境。它预见了对函数对象的需求:

http://doc.qt.io/archives/qt-4.7/qtconcurrentmap.html#using-function-objects

但是,我们不应该深入研究如何实现这一点,我们应该考虑为什么你一开始就想把它们作为成员函数。Map/Reduce模型允许您定义自定义累加器和结果类型,这可以在没有任何麻烦的情况下获得您想要的东西。这里有一个更简单的版本,希望它能编译并让你更接近:

代码语言:javascript
复制
#include <qlist.h>
#include <qtconcurrentmap.h>

#include <cmath> // for sin()
#include <algorithm> // for min, max, etc.
#include <limits> // for numeric_limits

struct MapResult // same as class, but "public" by default
{
    double input;
    double output;

    // must be "default constructible" due to guts of QtConcurrent :-/    
    // implementation artifact, don't worry about it affecting you...
    MapResult () {}

    MapResult (double input, double output) :
        // initializing members like this is cleaner than this->x = x...
        // and for certain members you HAVE to do it this way
        input (input), output (output)
    {
    }
};

struct ReduceAccumulator // same as class, but "public" by default
{
    MapResult largest;

    ReduceAccumulator () :
        // a better choice than 0 for an "uninitialized max" since
        // any other double will be larger...but you really should
        // probably accomodate a "no entries" case
        largest (MapResult (0, std::numeric_limits<double>::min())
    {
    }
};

// pattern of return type should be "U", not "const U" according to docs
MapResult mapFunction(const double& input) 
{
    // no need to construct a named local var if you don't want to
    // also no parentheses needed on return(x); ... return x; is fine 
    return MapResult (input, sin(input));
}

void reduceFunction(ReduceAccumulator& acc, const MapResult& oneResult)
{
    if (oneResult.output > acc.largest.output) {
        acc.largest = oneResult
    }
}

int main(int argc, char* argv[])
{
    QList<double> aList;
    for (int count = 8; count > 0; --count)
    {
        aList.append(rand());
    }

    ReduceAccumulator answer = QtConcurrent::blockingMappedReduced(
        aList, &mapFunction, &reduceFunction);

    return 0;
}

包括一些通用的C++注释,希望对您有所帮助。

UPDATE:他们提供的另一种方法确实使用了成员函数,但它做了一些与您试图编写的样式不同的假设。首先,它假设您的序列输入类型是一个类(double是"POD“或”普通旧数据“类型,并且没有方法分派)。则该参数是隐式的。

但请注意,如果您想使用这种技术,它将以一种特定的方式来样式化代码。以下是更改:

代码语言:javascript
复制
struct ReduceAccumulator
{
    MapResult largest;

    ReduceAccumulator () :
        largest (MapResult(0, std::numeric_limits<double>::min())
    {
    }

    // runs on non-const object, and drops first parameter (now implicit)
    void reduceFunction(const MapResult& oneResult)
    {
        if (oneResult.output > largest.output) {
            largest = oneResult
        }
    }
};

struct MyDouble {
    double d;

    MyDouble (double d) : d (d) {}

    // as member it takes no arguments, and needs to run on const objects
    MapResult mapFunction() const 
    {
        return MapResult (d, sin(d));
    }
};

int main(int argc, char* argv[])
{
    // to use a member as mapFunction, must be a member of input sequence type
    QList<MyDouble> aList;
    for (int count = 8; count > 0; --count)
    {
        aList.append(MyDouble (rand()));
    }

    ReduceAccumulator theAnswer = QtConcurrent::blockingMappedReduced(
        aList, &MyDouble::mapFunction, &ReduceAccumulator::reduceFunction);
}

你可以选择和choose...in这种情况下,可能更好做的reduceFunction作为一个成员。但是更改输入序列类型有点难看,而且这不是为进程设置参数的正确位置--您需要一个函数对象。

(还要记住,映射函数可以获得的可写状态会破坏MapReduce的并行性。map操作实际上应该只通过其结果生成输出,因此它们保持独立...)

票数 2
EN

Stack Overflow用户

发布于 2011-11-01 16:07:15

HostileFork:再次感谢您的帮助。你让我回到了让我真正的代码工作的轨道上来。

为了完整起见,这里是我的原始示例,其中包含了使blockingMappedReduced正常工作所需的最少更改(但仍然存在我混乱的C++样式问题)。这就是我如何通过你的解决方案来理解什么是什么。它可能会帮助其他人区分哪些是blockingMappedReduced问题,哪些是C++问题:

代码语言:javascript
复制
#include "stdafx.h"
#include <qlist.h>
#include <qtconcurrentmap.h>


// My class for the map/reduce functions
class myClass
{
    // Nested class to hold the intermediate results from the map function
    // I think I need this because the reduce function needs more from the map function than a single return value
    class Temp
    {
    public:

        // For example, let's pass these two member variables from the map function to the reduce function
        int randomInput;
        double resultingOutput;

        // default Temp constructor
        Temp()
        {
        };

        // The Temp constructor
        Temp(double randomInput, double resultingOutput)
        {
            this->randomInput = randomInput;
            this->resultingOutput = resultingOutput;
        }
    };

public:

    // For example, these myClass members will hold the final result from the reduce function
    double maximumOutput;
    double maximumInput;

    // The myClass constructor
    myClass()
    {
        this->maximumOutput = -1;
    }

    // The map function
    static Temp myClass::mapFunction(const int& randomInput)
    {
        // For example, let's calculate the sine of the given random number
        double resultingOutput = sin((double)randomInput);

        // Construct the temporary structure to pass multiple values to the reduce function
        Temp temp(randomInput, resultingOutput);
        return(temp);
    }

    // The reduce function
    static void myClass::reduceFunction(myClass& accumulator, const Temp& temp)
    {
        // For example, let's find the maximum computed sine value
        if (temp.resultingOutput > accumulator.maximumOutput)
        {
            accumulator.maximumOutput = temp.resultingOutput;
            accumulator.maximumInput = temp.randomInput;
        }
    }
};


// Main function
int main(int argc, _TCHAR* argv[])
{
    // Build a list of random numbers
    QList<int> aList;
    for (int count = 8; count > 0; --count)
    {
        aList.append(rand());
    }

    // Invoke the parallel map/reduce function
    myClass theAnswer = QtConcurrent::blockingMappedReduced(aList, &myClass::mapFunction, &myClass::reduceFunction);

    return(0);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7961043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档