There is a special description for move constructors and move assignment operators in the C++ Standard Library that says that the object the data is moved from is left in a valid but unspecified state after the call. Why? I frankly don't understand it. It is something I intuitively don't expect. Really, if I move something from one place to another in the real world, the place I move from is left empty (and yep, valid), until I move there something new. Why in the C++ world should it be different?
For example, depending on the implementation the following code:
std::vector<int> a {1, 2, 3};
std::vector<int> b {4, 5, 6};
a = std::move(b);
may be equivalent to the next code:
std::vector<int> a {1, 2, 3};
std::vector<int> b {4, 5, 6};
a.swap(b);
It is really what I don't expect. If I move the data from one vector to another, I expect the vector I move data from to be empty (zero size).
As far as I know the GCC implementation of the Standard C++ library leaves the vector in empty state after the move. Why not to make this behavior a part of the Standard?
What are the reasons to leave an object in unspecified state. If it is for optimization, it is kind of strange too. The only reasonable thing I can do with an object in unspecified state is to clear it (ok, I can get the size of the vector, I can print its content, but since the content is unspecified I don't need it). So the object will be cleared in any way either by me manually or by call of assignment operator or destructor. I prefer to clear it by myself, because I expect it to be cleared. But that's a double call to clear
. Where is an optimization?
string
, moving may not make the moved-from small string "empty". – Cageystd::shared_ptr
is guaranteed to leave the pointer moved-from in empty state. If I move the vector of shared_ptr to another vector, the first vector still may contain original shared_ptrs. That may cause a memory leak. The same withstd::function
. The lambda inside it can capture theshared_ptr
which may be left in the function move-from. It's better to clear it. – Haleighother
is guaranteed to beempty()
" -- so your question is based on a false premise. A moved-from object is left in an unspecified but valid state in the general case, then standard classes (or your own classes) can add sensible specifications. Same thing forstd::unique_ptr
andstd::shared_ptr
. – Trotylshared_ptr
can be copied.std::function
may have internal buffer to store data, and it is not required to move data, it may copy it (at least cppreference says that). So it may just copy the lambda with shared_ptrs from onestd::function
to another. – Haleighmove
implementation to make it work anyway. – Smollettmove
anymore, I usestd::swap
(which is usuallynoexcept
unlikemove
) and clear the second object manually. – Haleigh