Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QVector move semantics
Qt 6.11 is out! See what's new in the release blog

QVector move semantics

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 5 Posters 2.3k Views 3 Watching
  • 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.
  • Jimmy LoyolaJ Offline
    Jimmy LoyolaJ Offline
    Jimmy Loyola
    wrote on last edited by Jimmy Loyola
    #1

    Regarding Qt 4
    I guess first is copied and second is moved

    QVector<T> a;
    //...
    // a is copied or moved in b?
    QVector<T> b = a;
    

    Another case

    QVector<T> get()
    {
      QVector<T> k;
        //...
      return k;
    }
    
    // k is copied or moved in x?
    QVector<T>  x = get();
    
    jsulmJ 1 Reply Last reply
    1
    • Jimmy LoyolaJ Jimmy Loyola

      Regarding Qt 4
      I guess first is copied and second is moved

      QVector<T> a;
      //...
      // a is copied or moved in b?
      QVector<T> b = a;
      

      Another case

      QVector<T> get()
      {
        QVector<T> k;
          //...
        return k;
      }
      
      // k is copied or moved in x?
      QVector<T>  x = get();
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Jimmy-Loyola I don't think there is move constructor in QVector in Qt4.
      But this is not that important in Qt containers as they use implicit sharing: https://doc.qt.io/qt-5/implicit-sharing.html

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      Jimmy LoyolaJ 1 Reply Last reply
      6
      • Pl45m4P Offline
        Pl45m4P Offline
        Pl45m4
        wrote on last edited by
        #3

        Also:
        ( = operator)
        https://doc.qt.io/qt-5/qvector.html#operator-eq

        Move-ctor first in Qt 5.2
        https://doc.qt.io/qt-5/qvector.html#QVector-4


        If debugging is the process of removing software bugs, then programming must be the process of putting them in.

        ~E. W. Dijkstra

        1 Reply Last reply
        0
        • jsulmJ jsulm

          @Jimmy-Loyola I don't think there is move constructor in QVector in Qt4.
          But this is not that important in Qt containers as they use implicit sharing: https://doc.qt.io/qt-5/implicit-sharing.html

          Jimmy LoyolaJ Offline
          Jimmy LoyolaJ Offline
          Jimmy Loyola
          wrote on last edited by
          #4

          @jsulm I've got it. Thank you.

          J.HilkJ 1 Reply Last reply
          0
          • Jimmy LoyolaJ Jimmy Loyola

            @jsulm I've got it. Thank you.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by J.Hilk
            #5

            @Jimmy-Loyola also, if you explicitly want to move, there's always
            https://en.cppreference.com/w/cpp/utility/move

            that, as a template, can be applied to QtContainers, if they have a move constructor


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            Pl45m4P 1 Reply Last reply
            0
            • J.HilkJ J.Hilk

              @Jimmy-Loyola also, if you explicitly want to move, there's always
              https://en.cppreference.com/w/cpp/utility/move

              that, as a template, can be applied to QtContainers, if they have a move constructor

              Pl45m4P Offline
              Pl45m4P Offline
              Pl45m4
              wrote on last edited by
              #6

              @J-Hilk said in QVector move semantics:

              if they have a move constructor

              QVector doesnt seem to have one in Qt 4 :)
              Docs say, it was introduced in Qt 5.2.


              If debugging is the process of removing software bugs, then programming must be the process of putting them in.

              ~E. W. Dijkstra

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SimonSchroeder
                wrote on last edited by
                #7

                In the first case

                QVector<T> b = a;
                

                you are requesting a copy. As others have mentioned implicit sharing will not copy the data at this point, but it is basically a copy on write (if either a or b are changing the data). If you want to have a move you need to specify it explicitely:

                QVector<T> b = std::move(a);
                

                This depends on the Qt version if there is an actual move constructor available. This is general C++11 and not specific to Qt. Note that

                QVector<T> b = std::move(a);
                

                uses the move constructor if available (even though there is a = on this line), whereas

                b = std::move(a);
                

                uses move assignment (i.e. operator=) if available.


                The second case is a little trickier to answer. This has to do with return value optimization (allowed for long) and copy elision (allowed in C++11 and required in C++14 or C++17 – I don't remember). With copy elision compilers with the newest standard with neither copy nor move the variable in

                QVector<T> x = get();
                

                Instead, get()'s k-variable is directly constructed inside x's memory location (https://en.cppreference.com/w/cpp/language/copy_elision). I hope, I don't mix up 'required' and 'optional' here.

                There is a third variant to consider:

                QVector<T> get()
                {
                  QVector<T> k;
                  //...
                  return std::move(k);
                }
                
                QVector<T> x = get();
                

                This is a mistake people needed to be reminded of when C++11 was new. In the case presented by you return value optimization is possible. As soon as you add std::move in the return statement, a move is required. Instead of helping the compiler you are taking away the possibility for optimization.

                Jimmy LoyolaJ 1 Reply Last reply
                3
                • S SimonSchroeder

                  In the first case

                  QVector<T> b = a;
                  

                  you are requesting a copy. As others have mentioned implicit sharing will not copy the data at this point, but it is basically a copy on write (if either a or b are changing the data). If you want to have a move you need to specify it explicitely:

                  QVector<T> b = std::move(a);
                  

                  This depends on the Qt version if there is an actual move constructor available. This is general C++11 and not specific to Qt. Note that

                  QVector<T> b = std::move(a);
                  

                  uses the move constructor if available (even though there is a = on this line), whereas

                  b = std::move(a);
                  

                  uses move assignment (i.e. operator=) if available.


                  The second case is a little trickier to answer. This has to do with return value optimization (allowed for long) and copy elision (allowed in C++11 and required in C++14 or C++17 – I don't remember). With copy elision compilers with the newest standard with neither copy nor move the variable in

                  QVector<T> x = get();
                  

                  Instead, get()'s k-variable is directly constructed inside x's memory location (https://en.cppreference.com/w/cpp/language/copy_elision). I hope, I don't mix up 'required' and 'optional' here.

                  There is a third variant to consider:

                  QVector<T> get()
                  {
                    QVector<T> k;
                    //...
                    return std::move(k);
                  }
                  
                  QVector<T> x = get();
                  

                  This is a mistake people needed to be reminded of when C++11 was new. In the case presented by you return value optimization is possible. As soon as you add std::move in the return statement, a move is required. Instead of helping the compiler you are taking away the possibility for optimization.

                  Jimmy LoyolaJ Offline
                  Jimmy LoyolaJ Offline
                  Jimmy Loyola
                  wrote on last edited by
                  #8

                  @SimonSchroeder Your answer is very interesting. I will go into this.
                  Having all these things together can cause some confusion.
                  Thank you!

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved