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.
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.
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.
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.
Size of the vector is still 3
.