What are the iterator invalidation rules for C++ containers?
Preferably in a summary list format.
(Note: This is meant to be an entry to C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)
Answer
C++17 (All references are from the final working draft of CPP17 - n4659)
Sequence Containers
vector: The functionsinsert,emplace_back,emplace,push_backcause reallocation if the new size is greater than the old capacity. Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. If no reallocation
happens, all the iterators and references before the insertion point remain valid. [26.3.11.5/1]
With respect to thereservefunction, reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. No reallocation shall take place during insertions that happen after a call toreserve()until the time when an insertion would make the size of the vector greater than the value ofcapacity(). [26.3.11.3/6]deque: An insertion in the middle of the deque invalidates all the iterators and references to elements of the deque. An insertion at either end of the deque invalidates all the iterators to the deque, but has no effect on the validity of references to elements of the deque. [26.3.8.4/1]list: Does not affect the validity of iterators and references. If an exception is thrown there are no effects. [26.3.10.4/1].
Theinsert,emplace_front,emplace_back,emplace,push_front,push_backfunctions are covered under this rule.forward_list: None of the overloads ofinsert_aftershall affect the validity of iterators and references [26.3.9.5/1]array: As a rule, iterators to an array are never invalidated throughout the lifetime of the array. One should take note, however, that during swap, the iterator will continue to point to the same array element, and will thus change its value.
Associative Containers
All Associative Containers: Theinsertandemplacemembers shall not affect the validity of iterators and references to the container [26.2.6/9]
Unordered Associative Containers
All Unordered Associative Containers: Rehashing invalidates iterators, changes ordering between elements, and changes which buckets elements appear in, but does not invalidate pointers or references to elements. [26.2.7/9]
Theinsertandemplacemembers shall not affect the validity of references to container elements, but may invalidate all iterators to the container. [26.2.7/14]
Theinsertandemplacemembers shall not affect the validity of iterators if(N+n) <= z * B, whereNis the number of elements in the container prior to the insert operation,nis the number of elements inserted,Bis the container’s bucket count, andzis the container’s maximum load factor. [26.2.7/15]All Unordered Associative Containers: In case of a merge operation (e.g.,a.merge(a2)), iterators referring to the transferred elements and all iterators referring toawill be invalidated, but iterators to elements remaining ina2will remain valid. (Table 91 — Unordered associative container requirements)
Container Adaptors
stack: inherited from underlying containerqueue: inherited from underlying containerpriority_queue: inherited from underlying container
Sequence Containers
vector: The functionseraseandpop_backinvalidate iterators and references at or after the point of the erase. [26.3.11.5/3]deque: An erase operation that erases the last element of adequeinvalidates only the past-the-end iterator and all iterators and references to the erased elements. An erase operation that erases the first element of adequebut not the last element invalidates only iterators and references to the erased elements. An erase operation that erases neither the first element nor the last element of adequeinvalidates the past-the-end iterator and all iterators and references to all the elements of thedeque.
[ Note:pop_frontandpop_backare erase operations. —end note ] [26.3.8.4/4]list: Invalidates only the iterators and references to the erased elements. [26.3.10.4/3]. This applies toerase,pop_front,pop_back,clearfunctions.removeandremove_ifmember functions: Erases all the elements in the list referred by a list iteratorifor which the following conditions hold:*i == value,pred(*i) != false. Invalidates only the iterators and references to the erased elements [26.3.10.5/15].uniquemember function - Erases all but the first element from every consecutive group of equal elements referred to by the iteratoriin the range[first + 1, last)for which*i == *(i-1)(for the version of unique with no arguments) orpred(*i, *(i - 1))(for the version of unique with a predicate argument) holds. Invalidates only the iterators and references to the erased elements. [26.3.10.5/19]forward_list:erase_aftershall invalidate only iterators and references to the erased elements. [26.3.9.5/1].removeandremove_ifmember functions - Erases all the elements in the list referred by a list iterator i for which the following conditions hold:*i == value(forremove()),pred(*i)is true (forremove_if()). Invalidates only the iterators and references to the erased elements. [26.3.9.6/12].uniquemember function - Erases all but the first element from every consecutive group of equal elements referred to by the iterator i in the range [first + 1, last) for which*i == *(i-1)(for the version with no arguments) orpred(*i, *(i - 1))(for the version with a predicate argument) holds. Invalidates only the iterators and references to the erased elements. [26.3.9.6/16]All Sequence Containers:clearinvalidates all references, pointers, and iterators referring to the elements of a and may invalidate the past-the-end iterator (Table 87 — Sequence container requirements). But forforward_list,cleardoes not invalidate past-the-end iterators. [26.3.9.5/32]All Sequence Containers:assigninvalidates all references, pointers and
iterators referring to the elements of the container. Forvectoranddeque, also invalidates the past-the-end iterator. (Table 87 — Sequence container requirements)
Associative Containers
All Associative Containers: Theerasemembers shall invalidate only iterators and references to the erased elements [26.2.6/9]All Associative Containers: Theextractmembers invalidate only iterators to the removed element; pointers and references to the removed element remain valid [26.2.6/10]
Container Adaptors
stack: inherited from underlying containerqueue: inherited from underlying containerpriority_queue: inherited from underlying container
General container requirements relating to iterator invalidation:
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. [26.2.1/12]
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 ] [26.2.1/(11.6)]
As examples of the above requirements:
transformalgorithm: Theopandbinary_opfunctions shall not invalidate iterators or subranges, or modify elements in the ranges [28.6.4/1]accumulatealgorithm: In the range [first, last],binary_opshall neither modify elements nor invalidate iterators or subranges [29.8.2/1]reducealgorithm: binary_op shall neither invalidate iterators or subranges, nor modify elements in the range [first, last]. [29.8.3/5]
and so on...
No comments:
Post a Comment