Search code examples
c++vectormovemove-semantics

Why do moving vector and moving element have different effect on vector's size?


I know size() and empty() does not require precondition thus can be called on a moved-from object and return correct result. But I don't understand the theory behind the result.

std::vector<std::string> v = {"a", "b"};
std::string x = std::move(v[0]);
std::cout << x << std::endl;          // a
std::cout << v.size() << std::endl;   // 2
std::cout << v.empty() << std::endl;  // 0, false
auto y = std::move(v);                
std::cout << v.size() << std::endl;   // 0
std::cout << v.empty();               // 1, true

As the result shows, if you move an element, the size of vector won't change. But if you move the whole vector, it becomes empty. It makes sense, but I feel like needing more explanation so that I can handle similar cases in the future.


Solution

  • I want to answer this myself as I think some graph can help people(me included) understand this problem more easily.

    It all comes down to what's actually "moved". Let's say we have a vector of 3 strings.

    enter image description here

    Now, if I move the whole vector to say another vector, then everything on the heap is owned by the moved-to vector object, nothing is left seen from the moved-from vector's perspective.

    enter image description here

    Obviously, size of the vector becomes 0.

    If I move an element, which is a string in such case, only the string's data is gone. The data buffer of the vector is untouched.

    enter image description here

    Size of the vector is still 3.