STL: Vector and Sequence Containers · Lesson 18 of 33
Iterators in C++
An iterator is an object that points to an element of a container and can move to the next one. Every STL container provides iterators, and every STL algorithm works with them – which is what lets one std::sort or std::find work with any container. Think of them as generalised pointers.
In this lesson
begin(),end()and half-open ranges- Walking, reading and modifying through iterators
- Reverse and const iterators
- Iterator categories
begin, end and half-open ranges
#include <iostream>
#include <vector>
int main() {
std::vector<int> v{10, 20, 30, 40};
for (auto it = v.begin(); it != v.end(); ++it) { // what range-for does for you
*it += 1; // * gives the element
std::cout << *it << ' ';
}
std::cout << '\n';
auto it = v.begin() + 2; // jump (vector iterators are random access)
std::cout << "third: " << *it << ", index " << it - v.begin() << '\n';
std::cout << "elements: " << v.end() - v.begin() << '\n';
return 0;
}
11 21 31 41 third: 31, index 2 elements: 4
The half-open range [begin, end)
- 11begin()
- 21begin() + 1
- 31begin() + 2
- 41end() − 1
- —end(): one past the last – never dereference
Half-open ranges make an empty range simply begin == end, and the size end − begin. Every algorithm takes ranges this way: std::sort(v.begin(), v.end()), or just part of a container: std::sort(v.begin(), v.begin() + 3).
Iterators with algorithms
#include <algorithm>
#include <iostream>
#include <list>
#include <string>
#include <vector>
int main() {
std::vector<std::string> cities{"Pune", "Mumbai", "Delhi", "Kochi"};
auto it = std::find(cities.begin(), cities.end(), "Kochi");
if (it != cities.end()) std::cout << "found at index " << it - cities.begin() << '\n';
std::list<int> scores{72, 95, 41, 88}; // a different container, same algorithms
auto best = std::max_element(scores.begin(), scores.end());
std::cout << "best " << *best << ", count above 70: "
<< std::count_if(scores.begin(), scores.end(), [](int s) { return s > 70; }) << '\n';
std::sort(cities.begin() + 1, cities.end()); // sort only part of the range
for (const auto& c : cities) std::cout << c << ' ';
std::cout << '\n';
return 0;
}
found at index 3 best 95, count above 70: 3 Pune Delhi Kochi Mumbai
Reverse and const iterators
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
for (auto it = v.rbegin(); it != v.rend(); ++it) std::cout << *it << ' '; // backwards
std::cout << '\n';
for (auto it = v.cbegin(); it != v.cend(); ++it) {
// *it = 0; // error: cbegin gives a const_iterator (read-only)
std::cout << *it * 10 << ' ';
}
std::cout << '\n';
std::string s = "stressed";
std::cout << std::string(s.rbegin(), s.rend()) << '\n'; // build a string from a reversed range
return 0;
}
5 4 3 2 1 10 20 30 40 50 desserts
Iterator categories
| Category | Can do | Containers |
|---|---|---|
| Forward | ++it, read/write, multiple passes | forward_list, unordered_map/set |
| Bidirectional | also --it | list, set, map |
| Random access | also it + n, it[n], it2 − it1, < | vector, deque, array, string |
Algorithms state what they need. std::sort needs random-access iterators, so it doesn't work on a std::list – which has its own list.sort() member instead. std::next(it, n) and std::distance(a, b) work with any category.
Iterator safety
- Never dereference
end()– it's past the last element. - Don't compare iterators from different containers.
- Modifying a container (insert, erase, reallocation) can invalidate its iterators.
erasereturns the next valid iterator – use it when erasing in a loop.
Practice
Try it yourself
Use iterators to find the first and last even number in a vector.
Show solution
#include <algorithm> #include <iostream> #include <vector> int main() { std::vector<int> v{7, 4, 9, 12, 5, 8, 3}; auto even = [](int x) { return x % 2 == 0; }; auto first = std::find_if(v.begin(), v.end(), even); auto last = std::find_if(v.rbegin(), v.rend(), even); std::cout << "first " << *first << ", last " << *last << '\n'; return 0; }first 4, last 8
Quick check
What does end() point to?
One position past the last element – it must not be dereferenced.
Why can't std::sort sort a std::list?
It needs random-access iterators; list's are bidirectional (use list.sort()).
How do you get an element's index from a vector iterator?
it - v.begin().
Summary
- Iterators point into containers; ranges are half-open [begin, end).
- Algorithms take iterator ranges, so they work on any suitable container.
- rbegin/rend go backwards, cbegin/cend are read-only; categories decide which algorithms apply.
Finished this lesson?
Mark it complete to track your progress, then carry on with the next lesson.