Iterators
Master iterators, the glue between containers and algorithms that enables generic programming in C++
Learn how iterators serve as the bridge between containers and algorithms, enabling the power of generic programming in C++.
A Simple Example
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec{1, 2, 3, 4, 5};
// Iterator basics
std::vector<int>::iterator it = vec.begin();
std::cout << "First element: " << *it << "\n";
++it;
std::cout << "Second element: " << *it << "\n";
// Iterating through container
std::cout << "All elements: ";
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
std::cout << "\n";
// Const iterators (read-only)
std::vector<int>::const_iterator cit = vec.cbegin();
// Reverse iterators
std::cout << "Reversed: ";
for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
std::cout << *rit << " ";
}
std::cout << "\n";
return 0;
}
Breaking It Down
Iterator Basics: begin() and end()
-
What they do:
begin()returns an iterator to the first element,end()returns an iterator one past the last element - Half-open range: The range [begin, end) includes begin but excludes end
-
Why it matters: This design makes loops clean:
for (it = begin(); it != end(); ++it) -
Remember: Never dereference
end()- it points past the last valid element
Dereferencing Iterators: *it
-
What it does: Like pointers, use
*itto access the element the iterator points to -
Syntax:
*itreads the value,*it = valuemodifies it (if not const) - Use for: Getting or setting values at the current position
- Remember: Only dereference valid iterators between begin() and end()
Iterator Categories
- Input/Output: Single-pass, read or write only (stream iterators)
- Forward: Multi-pass, forward movement (std::forward_list)
- Bidirectional: Forward and backward (std::list, std::set, std::map)
- Random Access: Jump to any position (std::vector, std::deque)
- Remember: Algorithms require specific iterator categories
Const and Reverse Iterators
-
Const iterators: Use
cbegin()andcend()for read-only access -
Reverse iterators: Use
rbegin()andrend()to iterate backwards -
Auto keyword:
auto it = vec.begin();lets compiler deduce the type - Remember: Const iterators prevent accidental modification
Why This Matters
- Iterators are what make the STL truly powerful. They are the bridge between containers and algorithms, allowing you to write one algorithm that works with any container type.
- Understanding iterators unlocks the full potential of generic programming and makes you comfortable with the entire STL ecosystem.
Critical Insight
Iterators are the reason STL algorithms don't care what container you use. std::sort() works with vectors because it needs random access iterators. std::find() works with lists because it only needs forward iteration. This is abstraction at its finest - the algorithm describes what it needs, and the compiler ensures you are using compatible types. It is like having a universal adapter that makes everything work together!
Best Practices
Use auto for iterator types: auto it = vec.begin(); is cleaner and more maintainable than std::vector<int>::iterator it = vec.begin();.
Prefer range-based for loops: When you don't need the iterator itself, use for (const auto& elem : vec) instead of manual iteration.
Use const iterators when not modifying: Call cbegin() and cend() instead of begin() and end() to prevent accidental modification.
Never dereference end(): Always check it != container.end() before dereferencing to avoid undefined behavior.
Common Mistakes
Dereferencing end(): end() points PAST the last element - dereferencing it is undefined behavior and will likely crash.
Iterator invalidation: Modifying a container (insert, erase, push_back) can invalidate iterators. Always get fresh iterators after modifications.
Wrong iterator arithmetic: Only random access iterators support it + 5. Use std::advance(it, 5) for other iterator types.
Mixing iterator types: Don't compare iterators from different containers - it is undefined behavior.
Debug Challenge
This code has a bug when accessing the last element. Click the highlighted line to fix it:
Quick Quiz
- What does container.end() point to?
- Which iterator category supports it + 5?
- What is the purpose of const iterators (cbegin, cend)?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once