An iterator is considered invalidated if it no longer points to the same element it originally pointed to.
For std::deque
, the iterator invalidation rules are as follows:
end()
) is always invalidated when the deque is modified.push_front()
, emplace_front()
, push_back()
, emplace_back()
) only invalidates the end iterator.pop_front()
 or pop_back()
) only invalidates the end iterator and the iterators to the erased elements.clear()
 invalidates all iterators.swap()
 invalidates all iterators.Here's an example demonstrating iterator invalidation:
#include <deque>
#include <iostream>
int main() {
std::deque<int> d{1, 2, 3, 4, 5};
auto it = d.begin();
auto end = d.end();
d.push_front(0);
// This is fine, it still points to the element 1
std::cout << *it << "\n";
// This is invalid, end iterator is invalidated
std::cout << *(end - 1) << "\n";
d.insert(it + 2, 10);
// This is invalid, it no longer points to 1
std::cout << *it << "\n";
}
The previous example results in undefined behaviour. With debug flags enabled, the compiler may detect the problem and throw a run time error:
cannot deference out of range deque iterator
To avoid issues with iterator invalidation, it's often best to reacquire iterators after any operation that could potentially invalidate them.
Answers to questions are automatically generated and may not have been reviewed.
std::deque
A guide to double-ended queues - a structure that behaves like a vector, specialised for manipulating objects at the edges of the collection