Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should std::vector::swap() with stateful allocators invalidate all iterators?

Given allocators a1 and a2, where a1 != a2,

and std::vectors v1(a1) and v2(a2)

then v1.swap(v2) invalidates all iterators.

Is this expected behavior?

like image 503
jyoung Avatar asked Jun 12 '11 16:06

jyoung


People also ask

Does swap invalidate iterators?

The swap functions do not invalidate any of the iterators inside the container, but they do invalidate the iterator marking the end of the swap region.

Does std :: move invalidate iterators?

No, they should not get invalidated after a move operation.

Can I swap two vectors?

The std::vector::swap() function is used to swap the entire contents of one vector with another vector of same type. If std::swap() function is used for swapping two vectors A and B, it will call specialized std::swap algorithm for std::vector which in turn calls A. swap(B) and swaps the contents.


1 Answers

In general, swap never invalidates iterators. However, another rule comes into play when the allocators are different. In that case the behavior depends on allocator_traits<a1>::propagate_on_container_swap::value and allocator_traits<a2>::propagate_on_container_swap::value. If both are true, the allocators are exchanged along with the data, all iterators remain valid. If either is false, behavior is undefined, so the particular behavior exhibited by VC++ 2010 is allowed.

From [container.requirements.general] (wording from n3290):

Allocator replacement is performed by copy assignment, move assignment, or swapping of the allocator only if allocator_traits<allocatortype>::propagate_on_container_copy_assignment::value, allocator_traits<allocatortype>::propagate_on_container_move_assignment::value, or allocator_traits<allocatortype>::propagate_on_container_swap::value is true within the implementation of the corresponding container operation. The behavior of a call to a container’s swap function is undefined unless the objects being swapped have allocators that compare equal or allocator_traits<allocatortype>::propagate_on_container_swap::value is true.

and

Every iterator referring to an element in one container before the swap shall refer to the same element in the other container after the swap

and

Unless otherwise specified ... no swap() function invalidates any references, pointers, or iterators referring to the elements of the containers being swapped.

23.3.6.5 does not specify alternate rules for vector::swap().

like image 144
Ben Voigt Avatar answered Oct 23 '22 10:10

Ben Voigt