Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

    QtConcurrent::map with QList<Item*>

    General and Desktop
    3
    7
    6882
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • N
      nepomuk last edited by

      Hello folks,

      I want to use QtConcurrent::map for calling a member function (named extractFeatures) on every item of a QList. Unfortunately this doesn't work unless I change the list from QList<Item*> to QList<Item>. This is the code I wanted to use:

      @
      QFutureWatcher<void> watcher_ = new QFutureWatcher<void>;
      QList<Item
      > itemList = ...;

      watcher_->setFuture(QtConcurrent::map(itemList, &Item::extractFeatures));
      watcher_->waitForFinished();
      @

      This is the error I get:
      @c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore/qtconcurrentmapkernel.h:73:9: error: no match for call to '(QtConcurrent::MemberFunctionWrapper<void, Item>) (Item*&)'
      c:/QtSDK/Desktop/Qt/4.7.4/mingw/include/QtCore/qtconcurrentfunctionwrappers.h:119:14: note: candidate is: T QtConcurrent::MemberFunctionWrapper<T, C>::operator()(C&) [with T = void, C = Item]@

      Is there a way to call QtConcurrent::map() properly while maintaining the current data structure, that is, a QList of Item-Pointers?
      I would really appreciate any help. It's driving me mad.

      1 Reply Last reply Reply Quote 0
      • G
        goetz last edited by

        The "documentation":/doc/qt-4.8/qtconcurrentmap.html#map says:

        bq. Calls function once for each item in sequence. The function is passed a reference to the item, so that any modifications done to the item will appear in sequence.

        So the map method calls your function with a refrerence-to-pointer argument. To make your function work, you must change its argument to and make it work with a reference-to-pointer of Item too:

        @
        void Item::extractFeatures(Item *& item);
        @

        http://www.codeguru.com/cpp/cpp/cpp_mfc/pointers/article.php/c4089 and http://markgodwin.blogspot.com/2009/08/c-reference-to-pointer.html have some explanations.

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply Reply Quote 0
        • N
          nepomuk last edited by

          Thank you very much for this hint.
          Actually the function does not take any arguments:
          @void Item::extractFeatures();@
          The idea of this function is to modify some instance members of the class.

          In fact I want to do something like this (from the "documentation":http://developer.qt.nokia.com/doc/qt-4.8/qtconcurrentmap.html#using-member-functions):
          @
          // squeeze all strings in a QStringList
          QStringList strings = ...;
          QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);@
          QString::squeeze is a non-static void method of QString and it doesn't take any arguments, too.

          1 Reply Last reply Reply Quote 0
          • G
            goetz last edited by

            Oh, you're right. I don't know if it's possible to call a member function on a reference-to-pointer with QtConcurrent. I would try to implement a wrapper method that calls the other method on the pointer. But that's just a blind guess, it may fail too.

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply Reply Quote 0
            • N
              nepomuk last edited by

              Indeed this didn't work either. It seems as if it's not possible to use container of pointers with QtConcurrent.
              So I worked around this by iterating through the list and creating local copies of the items in a QList<Item>. This works though it's not very pretty. At least now I can take advantage of QtConcurrent and its automatic adjusting of the threads.
              Thank you anyway for your hints.

              1 Reply Last reply Reply Quote 0
              • G
                goetz last edited by

                You could try to use an external method for the concurrent map:

                @
                void extractFeaturesFromItem(Item *& item)
                {
                // do your work on item here
                }

                QFutureWatcher<void> watcher_ = new QFutureWatcher<void>;
                QList<Item
                > itemList = ...;

                // use the above proxy method for the map:
                watcher_->setFuture(QtConcurrent::map(itemList, &extractFeaturesFromItem));
                watcher_->waitForFinished();
                @

                It's not tested, just a wild guess again :)

                http://www.catb.org/~esr/faqs/smart-questions.html

                1 Reply Last reply Reply Quote 0
                • T
                  totem last edited by

                  it worked for me, thank you very much

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post