QVector move semantics
-
Regarding Qt 4
I guess first is copied and second is movedQVector<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();
-
@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 -
Also:
(=
operator)
https://doc.qt.io/qt-5/qvector.html#operator-eqMove-ctor first in Qt 5.2
https://doc.qt.io/qt-5/qvector.html#QVector-4 -
@Jimmy-Loyola also, if you explicitly want to move, there's always
https://en.cppreference.com/w/cpp/utility/movethat, as a template, can be applied to QtContainers, if they have a move constructor
-
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
orb
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), whereasb = 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()
'sk
-variable is directly constructed insidex
'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. -
@SimonSchroeder Your answer is very interesting. I will go into this.
Having all these things together can cause some confusion.
Thank you!