History of the issue:
Emerging in STL in C++98, iterators allowed abstraction from specific data structures, providing unified access to container elements. With the adoption of C++20, the standard ranges were added, further enhancing expressiveness and safety when working with containers.
Problem:
Incorrect usage of iterators can lead to runtime errors: going out of bounds of the container, invalidation after changes. Support for different types of iterators leads to unexpected behavior if they are confused with each other. Working "manually" with begin()/end() requires discipline.
Solution:
Use the iterator type appropriate for the container's capabilities (e.g., random access only for vector/deque/array). Do not store invalidated iterators. For modern tasks, it is more common to use standardized ranges and algorithms.
Code example:
#include <vector> #include <algorithm> #include <iostream> #include <ranges> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // Iteration through iterator for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // Iteration through range for (int x : vec | std::ranges::views::filter([](int v){return v % 2 == 0;})) { std::cout << x << " "; } return 0; }
Key features:
What happens to the std::vector iterator after calling push_back?
If the container size increases after push_back (rebalancing), all old iterators and references become invalid. After push_back without changing capacity, the iterators remain valid. It's safer not to store iterators between modifications.
What is the difference between random-access and bidirectional iterators?
Random-access supports arithmetic (it + n) and access by index (it[n]), while bidirectional supports only ++ and --. Not all STL containers support random-access.
Can standard STL algorithms work with regular pointers?
Yes, because a pointer in C++ fully meets the requirements of a random-access iterator.
In a loop over std::list, the developer directly modifies the container using the erase method without updating the iterator, leading to a runtime error.
Pros:
Cons:
Before modifying the container, the next iterator is always saved. Standard algorithms are used such as erase-remove idiom for vectors or list::remove_if for lists.
Pros:
Cons: