Standard specifies that STL containers, after begin moved (in this case we talk about std::move
that enables move construction / assignment), are in valid, but unspecified state.
I belive that means we can only apply operations that require no preconditions. I recall that someone here, on Stackoverflow, claimed that to be true and after some checking I agreed. Unfortunately, I cannot recall what sources have I checked. Furthermore, I was not able to find relevant information in the standard.
From [container.requirements.general/4]
, table 62
([tab:container.req]
), we can see that a.size()
has no preconditions. Does that mean this code is safe?
#include <iostream>
#include <vector>
int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1);
std::cout << v1.size(); // displaying size of the moved-from vector
}
It's unspecified what will this code print, but is it safe? Meaning, do we have undefined behaviour here?
EDIT: I don't believe this question will be too broad if I ask abour other containers. Will the answer be consistent among all other STL containers, including std::string
?
.size()
to return anything except0
here: the requirements onvector( vector&& )
are such that in the general case, the buffer must be moved to the target vector, and the source vector cannot hold onto anything and must be empty. However, an insane std library might be able to justify doing something different, especially for a vector of PODs. – Embodyvector(vector&& arg)
to simply call the relevantswap(*this, arg)
? Where does it say that the moved-from vector must be empty? – Winnaoperator=
, it is move-construction. There is nothing in the "destination" vector to swap out of. Extra allocations can (in general) be observed; so cannot occur. There are insane ways to get around this, but not in general. – Embody