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
Forum Updated to NodeBB v4.3 + New Features

QVector move semantics

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 5 Posters 2.1k 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