Iterators
Overview
If you have a Vector (Array) and a List (Linked List), writing a loop to read them requires entirely different syntax. A Vector uses arr[i], while a Linked List requires following memory pointers node = node->next.
Iterators are the brilliant bridge of the STL. An Iterator is an advanced, standardized Pointer. It abstracts away the complex memory architecture of the container. By using .begin() and .end(), you can loop through literally any STL container using the exact same standard syntax. This is what allows STL Algorithms to work on anything.
Syntax
#include <iostream>
#include <vector>
int main() {
std::vector<int> data = {10, 20, 30};
// 1. THE OLD, MESSY WAY (C++98)
// We physically create an iterator object pointing to the start
std::vector<int>::iterator it;
for (it = data.begin(); it != data.end(); it++) {
std::cout << *it << " "; // Dereference to get value
}
// 2. THE MODERN, CLEAN WAY (C++11 'auto')
// 'auto' forces the compiler to figure out the ugly iterator type!
for (auto iter = data.begin(); iter != data.end(); iter++) {
std::cout << *iter << " ";
}
return 0;
}Common Pitfalls
- Iterator Invalidation. If you create an Iterator pointing to the 5th element in a Vector, and then you
.push_back()a massive object that forces the Vector to reallocate its RAM to a new location... your Iterator is now pointing to dead memory! If you use it, the program crashes.
Interview Questions
.end() point to the last element in the container?NO! This is a massive trap. .end() strictly points to the memory address immediately after the last element. It represents the 'out of bounds' boundary. You can never dereference .end(). The actual last element is located at .end() - 1.
Real-World Example
Using Reverse Iterators (.rbegin() and .rend()) to effortlessly traverse a container backwards without calculating indices.
#include <iostream>
#include <vector>
int main() {
std::vector<int> countdown = {1, 2, 3, 4, 5};
// rbegin() points to 5. rend() points to the space before 1.
// Notice we still use iter++ to move forward through the reverse view!
for (auto iter = countdown.rbegin(); iter != countdown.rend(); iter++) {
std::cout << *iter << " ";
}
// Output: 5 4 3 2 1
return 0;
}Check Your Knowledge
Test your understanding of Iterators with these quick questions.