I'm bit confused regarding iterator invalidation in deque. (In the context of this question)
Following is the excerpts from -- The C++ Standard Library: A Tutorial and Reference, By Nicolai M. Josuttis
Any insertion or deletion of elements other than at the beginning or end invalidates all pointers, references, and iterators that refer to elements of the deque.
Following is the excerpts from SGI site:
The semantics of iterator invalidation for deque is as follows. Insert (including
push_front
andpush_back
) invalidates all iterators that refer to a deque. Erase in the middle of a deque invalidates all iterators that refer to the deque. Erase at the beginning or end of a deque (includingpop_front
andpop_back
) invalidates an iterator only if it points to the erased element.
IMHO, deque is collection of blocks with first block growing in one direction and the last block in opposite direction.
- - -
- - -
| - - ^
| - - |
V - - |
- - -
- - -
push_back, push_front
should not have any impact on deque iterators ( I agree with Josuttis).
What is the correct explanation? what the standard say on this?
To avoid invalidation of references to elements you can use a std::deque if you do not insert or erase in the middle. To avoid invalidation of iterators you can use a std::list.
What is Iterator Invalidation? An Iterator becomes invalidate when the container it points to changes its shape internally i.e. move elements from one location to another and the initial iterator still points to old invalid location.
Iterator Invalidation in C++ When the container to which an Iterator points changes shape internally, i.e. when elements are moved from one position to another, and the initial iterator still points to the old invalid location, then it is called Iterator invalidation. One should be careful while using iterators in C++.
No; all of the iterators at or after the iterator(s) passed to erase are invalidated. However, erase returns a new iterator that points to the element immediately after the element(s) that were erased (or to the end if there is no such element). You can use this iterator to resume iteration.
From the standard working draft
template < class InputIterator > void insert ( iterator position , InputIterator first , InputIterator last );
1 Effects: An insert in the middle of the deque invalidates all the iterators and references to elements of the deque. An insert 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."
So both are correct. As Josuttis indicates, insertion at the front or back doesn't invalidate references to elements of the deque, only iterators to the deque itself.
EDIT: A more up-to-date draft says essentially the same thing (section 23.2.2.3)
IMHO, deque is collection of blocks with first block growing in one direction and the last block in opposite direction.
Your opinion is your prerogative, but it's wrong. :)
deque
is such a container semantically, but in terms of implementation it's designed to be implemented by one or more blocks of memory. C++'s iterator invalidation rules come from implementation, so this is why. Arguably this is a small abstraction leak but, well, whatever.
The SGI STL documentation is not the proper documentation to read, because the SGI STL is not the C++ Standard Library. Unfortunately, Josuttis is one of those people who calls it "the STL", and this has led to your confusion.
Following is the excerpts from -- The C++ Standard Library: A Tutorial and Reference, By Nicolai M. Josuttis
Any insertion or deletion of elements other than at the beginning or end invalidates all pointers, references, and iterators that refer to elements of the deque.
Put simply, this passage from Josuttis is misleading in implying that the insertion or deletion of elements that are at the beginning or end do not invalidate pointers, references or iterators … though it's worth noting that he never comes out and asserts this outright.
Here are the real, proper, official rules for std::deque
:
Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all iterators are invalidated, but references to elements are unaffected) [23.2.1.3/1]
Erasure: all iterators and references are invalidated, unless the erased members are at an end (front or back) of the deque (in which case only iterators and references to the erased members are invalidated) [23.2.1.3/4]
Resizing: as per insert/erase [23.2.1.2/1]
Insertion: all iterators and references are invalidated, unless the inserted member is at an end (front or back) of the deque (in which case all iterators are invalidated, but references to elements are unaffected) [23.3.3.4/1]
Erasure: erasing the last element invalidates only iterators and references to the erased elements and the past-the-end iterator; erasing the first element invalidates only iterators and references to the erased elements; erasing any other elements invalidates all iterators and references (including the past-the-end iterator) [23.3.3.4/4]
Resizing: as per insert/erase [23.3.3.4/1]
I'm not sure what further reference to credible sources you're looking for — the relevant standard passage has already been cited and quoted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With