首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QtConcurrent错误:引用非静态成员

QtConcurrent错误:引用非静态成员
EN

Stack Overflow用户
提问于 2013-08-11 20:17:36
回答 2查看 1.5K关注 0票数 0

我正在使用OS-X10.8.4在Mac6.0上运行QT5.1和QtQuick 2.0。

由于我用文件I/O操作阻塞事件循环,我的QML变得没有响应。解决这个问题的通常方法是使用Will Bickford所讨论的多个线程( 这里 )。

为了做到这一点,我试图使用:

代码语言:javascript
复制
QtConcurrent::blockingMapped() 

它可能比使用显式QFuture对象更简单。我一直在阅读Qt文档很酷的例子,并运行了以下代码(以这个示例为模型):

代码语言:javascript
复制
// NOTE: this all seems to work:
#include <QList>
#include <iostream>
#include "dataobject.h"
#include <QtConcurrent/QtConcurrentMap>

DataObject load(const QString &file) {
    std::cout << "File I/O in thread = " << QThread::currentThread() << std::endl;
    return DataObject anObject(file);
}

int main(int argc, char *argv[])
{
    ...

    // Create a list of filenames:
    int count = 5;
    QList<QString> allFiles;
    for (int i = 0; i < count; i++) {
        allFiles.append(QString("aFileName"));
    }
    std::cout << "# of files = " << allFiles.size() << std::endl;

    QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles,load);
    std::cout << "# of objects = " << allTheDataObjects.size() << std::endl;

    ...
}

以下是DataObject的头文件和实现文件:

代码语言:javascript
复制
#include <QString>
class DataObject
{
public:
    DataObject();
    DataObject(QString filename);
    QString theFileName;
};
代码语言:javascript
复制
#include "dataobject.h"

DataObject::DataObject() {
    theFileName = QString("no file");
}
DataObject::DataObject(QString filename) {
    theFileName = filename;
    //...
    // Do file I/O stuff (slow) ...
}

这不是很现实,但作为一个简单的草图来说明我在下面遇到的问题。

当我试图在一个额外的"datamodel.h“类中封装QtConcurrent::块The ()时,就会出现这个问题:

代码语言:javascript
复制
#include "dataobject.h"
class DataModel
{
public:
    DataModel();
    void runConcurrent();
    DataObject load(const QString& fileList);
};
代码语言:javascript
复制
#include "datamodel.h"
#include <QtConcurrent/QtConcurrentMap>
#include <iostream>

DataModel::DataModel() {}
DataObject DataModel::load(const QString &file) {
    std::cout << "File I/O in thread = " << QThread::currentThread() << std::endl;
    return DataObject anObject(file);
}
void DataModel::runConcurrent() {
    // Create a list of filenames:
    int count = 5;
    QList<QString> allFiles;
    for (int i = 0; i < count; i++)
        allFiles.append(QString("dummyFileName"));
    QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles, this->load);
    std::cout << "# of objects = " << allTheDataObjects.size() << std::endl;
}

然后main()变成(注意,我还将load()方法移到DataModel类中):

代码语言:javascript
复制
#include <QList>
#include <iostream>
#include "dataobject.h"
#include "datamodel.h"
#include <QtConcurrent/QtConcurrentMap>

int main(int argc, char *argv[])
{
    ...

    DataModel theModel;
    theModel.runConcurrent();

    ...
}

但是现在有一个编译器错误:

代码语言:javascript
复制
datamodel.cpp: error: reference to non-static member function must be called:
QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles, this->load);

我无法通过初始化一个DataObject或DataModel实例来修复编译器错误(这样可以看到一个非静态成员函数),并且不确定还可以尝试什么。

接下来,我怀疑这可能是由于设置QtConcurrent参数时出现了“函子”绑定问题(我没有增强安装,所以不使用助推::绑定),所以我尝试了使用C++ 11 lambda的席的建议,方法是替换:

代码语言:javascript
复制
this->load

通过以下方式:

代码语言:javascript
复制
[this](const QString& file){load(file);}

给出密码:

代码语言:javascript
复制
QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles, 
                                       [this](const QString& file){load(file);});

现在我不再获得非静态成员错误,但是出现了一个新的错误(指向上面的行):

代码语言:javascript
复制
datamodel.cpp: error: expected expression:

我在这个问题上犯了很大的错误,这可能是个简单的错误,但我很难把它弄清楚。

有人能帮忙吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-13 18:11:44

好的,开始工作了。

如果这样做对那些不想处理绑定或编写自己的“函子”的人有好处(下面的方法要简单得多):

首先,在datamodel.h文件中为"load“函数使用静态类型:

代码语言:javascript
复制
static DataObject load(const QString& fileList);

这是因为可以调用C++类的静态函数,而不需要实例化对象。

然后,在datamodel.cpp文件中,它是这样简单的:

代码语言:javascript
复制
DataModel::load 

给予:

代码语言:javascript
复制
QList<DataObject> allTheDataObjects = 
                      QtConcurrent::blockingMapped(allFiles, DataModel::load);

然后,代码按预期运行。

票数 0
EN

Stack Overflow用户

发布于 2013-08-11 21:35:03

显然,您没有使用C++11,它有lambda表达式。因此,使用来自STL的绑定或Boost或创建function。

代码语言:javascript
复制
QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles, 
                                   std::bind1st(std::mem_fun(&DataModel::load), this));

好的,上面的解决方案不能使用引用(知道错误)。定义函子(或使用Boost::bind):

代码语言:javascript
复制
class LoadDataModel /*: public std::unary_function<QString, DataObject>*/ {
public:
    LoadDataModel(DataModel *p) : d(p) {}

    DataObject operator()(const QString &s) const {
        return d->load(s);
    }
private:
    DataModel *d;
}

QList<DataObject> allTheDataObjects = QtConcurrent::blockingMapped(allFiles, LoadDataModel(this));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18176258

复制
相关文章

相似问题

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