C++ Iterators
A C++ iterator is an object that represents a position inside a container. Iterators let you move through STL containers and give algorithms a common way to work with many container types.
You can think of an iterator as a pointer-like tool: it can refer to an element, move to another element, and be compared with another iterator.
Begin and End
Most STL containers have begin() and end() member functions. begin() returns an iterator to the first element. end() returns an iterator just past the last element.
The end() iterator does not refer to a real element. It is a stopping point, so you should not dereference it.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> numbers = {10, 20, 30};
for (std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
Output:
10
20
30
The variable it starts at the first element. The expression it != numbers.end() keeps the loop running until the iterator reaches the stopping position. The expression *it dereferences the iterator, giving access to the value it currently points to.
Dereferencing and Moving
Dereferencing an iterator uses the same * operator you saw with pointers. Incrementing an iterator with ++it moves it to the next position.
If the iterator is not end(), you can read or change the element through it. This example changes the first value, then prints every value.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> scores = {75, 80, 90};
std::vector<int>::iterator first = scores.begin();
*first = 100;
for (std::vector<int>::const_iterator it = scores.begin(); it != scores.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
Output:
100
80
90
The first iterator can modify the vector because it is a normal iterator. The loop uses a const_iterator, which is useful when you only need to read values.
Iterators and Algorithms
STL algorithms usually take iterator ranges. A range is written as a pair of iterators: the first position to include and the ending position to stop before.
This is why many algorithm calls look like container.begin(), container.end(). The algorithm does not need to know the exact container name; it only needs a range of elements.
#include <algorithm>
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> values = {4, 8, 15, 16, 23, 42};
std::vector<int>::iterator found = std::find(values.begin(), values.end(), 16);
if (found != values.end()) {
std::cout << "Found: " << *found << std::endl;
}
std::cout << "Values from 15 onward:" << std::endl;
for (std::vector<int>::iterator it = values.begin() + 2; it != values.end(); ++it) {
std::cout << *it << std::endl;
}
return 0;
}
Output:
Found: 16
Values from 15 onward:
15
16
23
42
std::find() searches the iterator range from values.begin() up to values.end(). If the value is found, it returns an iterator to that element. If not, it returns values.end().
Iterator Types
Different containers support different iterator abilities. A vector iterator can move forward, move backward, and jump by an index-like offset such as + 2. A list iterator can move forward and backward, but it cannot jump directly by offset.
| Iterator idea | Meaning |
|---|---|
iterator |
Can usually read and modify elements |
const_iterator |
Can read elements but cannot modify them |
begin() |
Iterator to the first element |
end() |
Iterator just past the last element |
*it |
The element at the iterator position |
++it |
Move the iterator to the next position |
Common Mistakes
- Do not dereference
end(). It is only a stopping marker. - Check that an algorithm result is not
end()before using*result. - Use
const_iteratorwhen you want to read without changing elements. - Remember that not every container supports iterator arithmetic such as
it + 2.
Takeaway: iterators are the link between STL containers and STL algorithms, marking where a range begins, where it ends, and which element is currently being used.
