Considering this example:
std::vector<int> v1 = { 1, 2, 3 };
const int* i = &v1[1];
std::vector<int> v2(std::move(v1));
std::cout << *i << std::endl;
Even though in many STL implementations this will probably work, am I guaranteed by the standard that no reallocations are performed when a std::vector
is moved, and the internal buffer backing v2
is the same that used to be the one of v1
? I wasn't able to find this information neither on the Internet, nor on the standard itself.
This is LWG open issue 2321 [emphasis mine]
Moving containers should (usually) be required to preserve iterators
[...]
[by Stephan T. Lavavej]
23.2.1 [container.requirements.general]/10 says that unless otherwise specified, "no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped. [Note: The end() iterator does not refer to any element, so it may be invalidated. — end note]". However, move constructors and move assignment operators aren't given similar invalidation guarantees. The guarantees need several exceptions, so I do not believe that blanket language like /11 "Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container." is applicable.[2014-02-13 Issaquah]
General agreeement on intent, several wording nits and additional paragraphs to hit.
STL to provide updated wording. Move to Open.
Proposed resolution:
[...]
no move constructor [...] of a container (except for
array
) invalidates any references, pointers, or iterators referring to the elements of the source container. [Note: Theend()
iterator does not refer to any element, so it may be invalidated. — end note]
So, this is an open issue, with general agreement on its basic solution (pointer shall not be invalidated by moving). However, it isn't officially accepted (yet?) as a defect. As far as I know, all major implementations do not invalidate pointers when move-constructing, and it seems to be a generally (implicitly) provided guarantee.