QtConcurrent :: map()与成员函数=无法编译

her*_*ong 2 qt multithreading qtconcurrent

我的项目是创建一个小程序,演示搜索引擎的工作:索引和返回任意查询的结果.我已经完成了索引器部分的工作,现在我想通过一次索引多个文件来改进它.MainWindow类在这里:

class MainWindow : public QMainWindow
{
    Q_OBJECT
    .....
private:
    Indexer * indexer;
    QStringList fileList;
    ....
    void index(QStringList list);
    void add(const QString &filename);
}
Run Code Online (Sandbox Code Playgroud)

这是执行add(add需要访问fileList以避免再次索引相同的文件,因此它不能是静态方法):

void MainWindow::add(const QString &filename)
{
    if (!fileList.contains(filename))
    {
        indexer->addDocument(filename.toStdString());
        fileList.append(filename);
        qDebug() << "Indexed" << filename;
        emit updatedList(fileList);
    }
}
Run Code Online (Sandbox Code Playgroud)

index方法的实现是接收文件列表并调用add每个文件名:

void MainWindow::index(QStringList list)
{
    ....
    QtConcurrent::map(list, &MainWindow::add);
    ....
}
Run Code Online (Sandbox Code Playgroud)

我在编译这些代码时收到的错误是:

usr/include/qt4/QtCore/qtconcurrentmapkernel.h: In member function 'bool QtConcurrent::MapKernel<Iterator, MapFunctor>::runIteration(Iterator, int, void*) [with Iterator = QList<QString>::iterator, MapFunctor = QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>]':
../search-engine/mainwindow.cpp:361:1:   instantiated from here
/usr/include/qt4/QtCore/qtconcurrentmapkernel.h:73:9: error: no match for call to '(QtConcurrent::MemberFunctionWrapper1<void, MainWindow, const QString&>) (QString&)'
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:128:7: note: candidate is:
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note: T QtConcurrent::MemberFunctionWrapper1<T, C, U>::operator()(C&, U) [with T = void, C = MainWindow, U = const QString&]
/usr/include/qt4/QtCore/qtconcurrentfunctionwrappers.h:138:14: note:   candidate expects 2 arguments, 1 provided
Run Code Online (Sandbox Code Playgroud)

我对QtConcurrent的工作原理并不熟悉,文档也没有提供太多关于它的细节.我真的希望这里有人可以提供帮助.提前致谢.

Mat*_*Mat 8

为了能够调用指向成员的指针,除了函数形式参数之外,还需要该类的实例(this成员函数内部的指针).

有两种方法可以解决这个问题:创建一个简单的函子来包装调用,或使用lambda.

仿函数看起来像这样:

struct AddWrapper {
  MainWindow *instance;
  AddWrapper(MainWindow *w): instance(w) {}
  void operator()(QString const& data) {
    instance->add(data);
  }
};
Run Code Online (Sandbox Code Playgroud)

你会像以下一样使用它:

AddWrapper wrap(this);
QtConcurrent::map(list, wrap);
Run Code Online (Sandbox Code Playgroud)

(小心那个包装器的生命周期.你可以使它更通用 - 例如,你也可以在包装器中存储指向成员的指针,和/或如果你想为其他类型重用该结构,使其成为模板.)

如果你有一个带有lambda的C++ 11编译器,你可以避免所有的例子:

QtConcurrent::map(list, [this] (QString const& data) { add(data); });
Run Code Online (Sandbox Code Playgroud)

注意:我不确定QtConcurrent::MemberFunctionWrapper1你的例子是如何参与的,我在这里没有看到它.因此,对于这种情况,Qt中可能已存在通用包装器,但我不知道它.