Move with vector::push_back

C++C++11

C++ Problem Overview


Suppose I have the following code:

#include <vector>
struct A {
    int a;
    int x;
};
int main() {
    using namespace std;
    A a1;
    A a2;
    vector<A> va;
    va.push_back(a1);
    va.push_back(move(a2));
}

I am aware that the elements of std::vector are stored contiguously, unlike a std::list. In the above code a2 is moved but is there really no copying of a2 to the vector va? What is the difference between va.push_back(a2); and va.push_back(move(a2));?

C++ Solutions


Solution 1 - C++

In your case, there is no effective difference, since you are using compiler-provided copy constructors. You would see a noticeable performance difference when using objects that are move-constructible, and take a lot of effort to copy. In that case, using push_back(x) would create a copy of the object, while push_back(move(x)) would tell push_back() that it may "steal" the contents of x, leaving x in an unusable and undefined state.

Consider if you had a vector of lists (std::vector<std::list<int> >) and you wanted to push a list containing 100,000 elements. Without move(), the entire list structure and all 100,000 elements will be copied. With move(), some pointers and other small bits of data get shuffled around, and that's about it. This will be lots faster, and will require less overall memory consumption.

Solution 2 - C++

When you use va.push_back(a2) version vector<T>::push_back(const T&) will be called, when you use va.push_back(move(a2)) version vector<T>::push_back(T&&) will be called...

But in your case there is no difference for perfomance, since

> 15 The implicitly-defined copy/move constructor for a non-union class > X performs a memberwise copy/move of its bases and members.

Paragraph 12.8 n3337 draft.

Solution 3 - C++

I want to note something that other answers didn't have gone over; is that the ?.push_back(move(?)) will be slower than ?.push_back(?) in your case (when you have trivially copyable objects), because move constructor need to zero\set the moved object, which effectively you are writing\copying two objects.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongggView Question on Stackoverflow
Solution 1 - C++cdhowieView Answer on Stackoverflow
Solution 2 - C++ForEveRView Answer on Stackoverflow
Solution 3 - C++LyingOnTheSkyView Answer on Stackoverflow