代码之家  ›  专栏  ›  技术社区  ›  CybeX

Qt::与成员函数并发映射

  •  0
  • CybeX  · 技术社区  · 6 年前

    我想用 QtConcurrent::mapped() 功能,但通过 QtConcurrent examples 提供并试图找到一个可用的例子来扩展到我的使用是困难的。

    在示例中,Qt maps

    QtConcurrent::map() QFuture<void> . 不过,我希望返回结果,即。 QFuture<SomeStructOrType>

    我想在其中使用的示例/场景是UI应用程序中的一个密集工作负载,但一个简单的示例可能是:

    class MainWindow : public QMainWindow {
         Q_OBJECT
    
      public:
         // The struct is to demonstrate a datatype more complex than int / QString
         struct IntStruct {
             int i;
         };
    
         MainWindow(QWidget* parent = nullptr);
         IntStruct doubleValue(IntStruct i);
         ~MainWindow();
    
    private:
       Ui::MainWindow* ui;
       // To watch progress and act upon progress change
       QFutureWatcher<IntStruct> futureWatcher;
    
       // Member to keep track of mapped process
       QFuture<IntStruct> future;
    
       //...
    }
    

    执行情况如下:

    MainWindow::MainWindow(QWidget* parent)
         : QMainWindow(parent)
         , ui(new Ui::MainWindow)
    {
         ui->setupUi(this);
    
         // Input Sequence/Iterator to perform doubleValue function on
         QList<IntStruct> intList = QList<IntStruct>();
         for (int i = 0; i < 1000; i++) {
             IntStruct s;
             s.i = qrand();
             intList.append(s);
         }
    
         // Watch future and report on result ready (process a result when done)
         connect(&futureWatcher, &QFutureWatcher<IntStruct>::resultReadyAt, this, [intList](int index){
             qDebug() << QString("[index = %1] value = %2").arg(QString::number(index), QString::number(intList.at(index).i));
         });
    
         //typedef IntStruct (MainWindow::*doubleValueFunction)(IntStruct);
         //doubleValueFunction memberFunction = this->doubleValue;             // this->doubleValue error: reference to non-static member function must be called ???
    
         // Run future - this doubleValue function should be a pointer to an instance function, how to do so?         
         future = QtConcurrent::mapped(intList, &MainWindow::doubleValue);
         futureWatcher.setFuture(future);
    }
    
    // Some complex member function
    MainWindow::IntStruct MainWindow::doubleValue(MainWindow::IntStruct i)
    {
        i.i *= i.i;
        return i;
    }
    

    我知道QtConcurrent允许lambdas,但是我需要使用一个成员函数。

    我还尝试用lambda来使用指向当前实例的指针,但它给了我一个错误信息,您可以找到 here .

     future = QtConcurrent::mapped(intList, [this](IntStruct &i){
         this->doubleValue(i);
     });
    

    TL;博士 所以基本上,我怎么用 QtConcurrent::mapped(


    悬赏问题的更新

    这在屏幕上显示

    enter image description here

    ..\ThreadTester\mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)':
    ..\ThreadTester\mainwindow.cpp:27:69: error: no match for 'operator=' (operand types are 'QFuture<MainWindow::IntStruct>' and 'QFuture<void>')
          future = QtConcurrent::mapped(intList, &MainWindow::doubleValue);
                                                                         ^
    In file included from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/QFuture:1:0,
                     from ..\ThreadTester\thread.h:10,
                     from ..\ThreadTester\mainwindow.h:6,
                     from ..\ThreadTester\mainwindow.cpp:1:
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/qfuture.h:59:7: note: candidate: QFuture<MainWindow::IntStruct>& QFuture<MainWindow::IntStruct>::operator=(const QFuture<MainWindow::IntStruct>&)
     class QFuture
           ^~~~~~~
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/qfuture.h:59:7: note:   no known conversion for argument 1 from 'QFuture<void>' to 'const QFuture<MainWindow::IntStruct>&'
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/qfuture.h:59:7: note: candidate: QFuture<MainWindow::IntStruct>& QFuture<MainWindow::IntStruct>::operator=(QFuture<MainWindow::IntStruct>&&)
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtCore/qfuture.h:59:7: note:   no known conversion for argument 1 from 'QFuture<void>' to 'QFuture<MainWindow::IntStruct>&&'
    In file included from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentfilterkernel.h:48:0,
                     from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtConcurrent/qtconcurrentfilter.h:47,
                     from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtConcurrent/QtConcurrent:8,
                     from ..\ThreadTester\thread.h:11,
                     from ..\ThreadTester\mainwindow.h:6,
                     from ..\ThreadTester\mainwindow.cpp:1:
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentmapkernel.h: In instantiation of 'QtConcurrent::ThreadEngineStarter<T> QtConcurrent::startMapped(const Sequence&, Functor) [with T = void; Sequence = QList<MainWindow::IntStruct>; Functor = QtConcurrent::MemberFunctionWrapper1<MainWindow::IntStruct, MainWindow, MainWindow::IntStruct>]':
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtConcurrent/qtconcurrentmap.h:132:88:   required from 'QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> QtConcurrent::mapped(const Sequence&, MapFunctor) [with Sequence = QList<MainWindow::IntStruct>; MapFunctor = MainWindow::IntStruct (MainWindow::*)(MainWindow::IntStruct); typename QtPrivate::MapResultType<void, MapFunctor>::ResultType = void]'
    ..\ThreadTester\mainwindow.cpp:27:69:   required from here
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentmapkernel.h:237:71: error: could not convert 'QtConcurrent::startThreadEngine(ThreadEngine*) [with ThreadEngine = QtConcurrent::SequenceHolder1<QList<MainWindow::IntStruct>, QtConcurrent::MappedEachKernel<QList<MainWindow::IntStruct>::const_iterator, QtConcurrent::MemberFunctionWrapper1<MainWindow::IntStruct, MainWindow, MainWindow::IntStruct> >, QtConcurrent::MemberFunctionWrapper1<MainWindow::IntStruct, MainWindow, MainWindow::IntStruct> >; typename ThreadEngine::ResultType = MainWindow::IntStruct]()' from 'QtConcurrent::ThreadEngineStarter<MainWindow::IntStruct>' to 'QtConcurrent::ThreadEngineStarter<void>'
         return startThreadEngine(new SequenceHolderType(sequence, functor));
                                                                           ^
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentmapkernel.h: In instantiation of 'bool QtConcurrent::MappedEachKernel<Iterator, MapFunctor>::runIteration(Iterator, int, QtConcurrent::MappedEachKernel<Iterator, MapFunctor>::T*) [with Iterator = QList<MainWindow::IntStruct>::const_iterator; MapFunctor = QtConcurrent::MemberFunctionWrapper1<MainWindow::IntStruct, MainWindow, MainWindow::IntStruct>; QtConcurrent::MappedEachKernel<Iterator, MapFunctor>::T = MainWindow::IntStruct]':
    ..\ThreadTester\mainwindow.cpp:36:1:   required from here
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentmapkernel.h:175:17: error: no match for call to '(QtConcurrent::MemberFunctionWrapper1<MainWindow::IntStruct, MainWindow, MainWindow::IntStruct>) (const MainWindow::IntStruct&)'
             *result = map(*it);
    In file included from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtConcurrent/qtconcurrentfilter.h:48:0,
                     from F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include\QtConcurrent/QtConcurrent:8,
                     from ..\ThreadTester\thread.h:11,
                     from ..\ThreadTester\mainwindow.h:6,
                     from ..\ThreadTester\mainwindow.cpp:1:
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentfunctionwrappers.h:132:14: note: candidate: T QtConcurrent::MemberFunctionWrapper1<T, C, U>::operator()(C&, U) [with T = MainWindow::IntStruct; C = MainWindow; U = MainWindow::IntStruct]
         inline T operator()(C &c, U u)
                  ^~~~~~~~
    F:\Qt\Qt5.13.1\5.13.1\mingw73_32\include/QtConcurrent/qtconcurrentfunctionwrappers.h:132:14: note:   candidate expects 2 arguments, 1 provided
    mingw32-make[1]: *** [Makefile.Debug:1117: debug/mainwindow.o] Error 1
    mingw32-make[1]: *** Waiting for unfinished jobs....
    mingw32-make[1]: Leaving directory 'C:/Users/CybeX/QtProjects/build-ThreadTester-Desktop_Qt_5_13_1_MinGW_32_bit-Debug'
    mingw32-make: *** [Makefile:38: debug] Error 2
    

    mapped() 返回一些数据类型U。如果我更改了 QFuture<IntStruct> 未来<无效> ,每个人都很高兴,但我无法收集任何违背 首先要发挥作用。

    0 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc    6 年前

    你必须使用 std::bind :

    #include <functional>
    
    # ....
    
    future = QtConcurrent::mapped(intList,
                                  std::bind(&MainWindow::doubleValue,
                                            this,
                                            std::placeholders::_1));