Iterator in C++ is one of the most important ideas in the Standard Template Library because iterators provide a general way to move through container elements. Instead of writing completely different traversal logic for arrays, vectors, lists, sets, and maps, C++ uses iterators as a common abstraction. This is one of the reasons STL containers and STL algorithms work together so cleanly. If containers are about storing data, iterators are about reaching that data in a standard way.
This topic matters because many STL algorithms do not operate directly on containers. They operate on iterator ranges. Functions like sort(), find(), count(), and reverse() expect iterators rather than special-case code for each container. That means if you understand iterators properly, a large part of STL starts to feel coherent instead of scattered. Iterators are one of the main bridges between containers and algorithms in modern C++.
What Is an Iterator in C++?
An iterator in C++ is an object that points to an element inside a container and allows you to move through the elements one by one or according to the rules supported by that iterator type. A good mental model is that an iterator behaves somewhat like a generalized pointer. It does not have to be an actual raw pointer, but it often supports pointer-like operations such as dereferencing and incrementing.
In simple terms, iterators let a program say “start here,” “move to the next element,” and “stop when the range ends.” That common behavior makes generic algorithms possible across many different container types.
Iterator in C++ is a generalized pointer-like object used to access and traverse elements in STL containers.
Why Iterators Are Needed in C++
Different containers have different internal structures. A vector stores elements in contiguous memory, a list stores linked nodes, and a map stores ordered key-value nodes. If every algorithm had to know the internal structure of every container, STL would become far more complex. Iterators solve this by giving algorithms a common interface for element access and traversal.
- Iterators provide a standard traversal mechanism for different containers.
- Iterators let algorithms work generically on ranges instead of one container type only.
- Iterators reduce duplicated traversal logic in library design.
- Iterators help separate data storage from data processing.
This design is one of the biggest reasons the STL is elegant. Containers manage storage, iterators expose traversal, and algorithms operate on iterator ranges.
Basic Syntax of Iterator in C++
An iterator type is usually available through the container type itself.
std::vector<int> values = {10, 20, 30};
std::vector<int>::iterator it = values.begin();
Here it is an iterator pointing to the first element of the vector. You can access the element with dereferencing and move to the next one with increment.
std::cout << *it << std::endl;
++it;
std::cout << *it << std::endl;
begin() and end() in C++
Most STL containers provide begin() and end() member functions. begin() returns an iterator to the first element. end() returns an iterator pointing one position past the last element. That end iterator does not refer to a valid element to print directly. It is used as a stopping boundary.
for (auto it = values.begin(); it != values.end(); ++it)
{
std::cout << *it << " ";
}
This pattern is one of the most fundamental iterator loops in C++.
Basic Iterator Operations
The exact operations depend on the iterator category, but the most common iterator actions are easy to recognize.
*itdereferences the iterator to access the current element.++itmoves the iterator forward.--itmoves backward for iterators that support it.it1 == it2andit1 != it2compare iterator positions.
For some containers and iterator types, more advanced operations such as addition, subtraction, or indexing are also possible.
Types of Iterators in C++
Not all iterators are equally powerful. STL defines categories based on the operations they support.
| Iterator Type | Main Capability |
|---|---|
| Input iterator | Read values while moving forward |
| Output iterator | Write values while moving forward |
| Forward iterator | Move forward and revisit positions in one direction |
| Bidirectional iterator | Move both forward and backward |
| Random access iterator | Jump directly with arithmetic and indexing-style movement |
This classification matters because some algorithms require stronger iterator abilities than others. For example, sort() normally expects random access iterators, so it works naturally with vectors and deques but not in the same way with a list.
Container Iterator Examples
Different containers expose iterators, but their capabilities depend on the underlying data structure.
| Container | Typical Iterator Strength |
|---|---|
vector | Random access iterator |
deque | Random access iterator |
list | Bidirectional iterator |
set | Bidirectional iterator |
map | Bidirectional iterator |
This helps explain why not all algorithms apply equally to all containers. Iterator category is one of the hidden rules behind STL behavior.
Const Iterators in C++
A const iterator is used when you want to traverse a container without modifying its elements through that iterator. This improves clarity and prevents accidental writes.
std::vector<int> values = {1, 2, 3};
for (std::vector<int>::const_iterator it = values.begin(); it != values.end(); ++it)
{
std::cout << *it << " ";
}
With a const iterator, the traversal still works normally, but writing through *it is not allowed.
Reverse Iterators in C++
STL containers also provide reverse iterators for backward traversal. Instead of begin() and end(), reverse traversal typically uses rbegin() and rend().
for (auto it = values.rbegin(); it != values.rend(); ++it)
{
std::cout << *it << " ";
}
This is useful when order matters and you need to process elements from the end toward the beginning.
Iterator with STL Algorithms
One of the most important uses of iterators is working with STL algorithms. Algorithms usually expect a range defined by two iterators.
std::vector<int> values = {4, 1, 7, 2};
std::sort(values.begin(), values.end());
auto it = std::find(values.begin(), values.end(), 7);
Here iterators connect the container to the algorithms. The same pattern appears throughout STL, which is why iterators are such a central concept.
Iterator Invalidation in C++
One important practical topic is iterator invalidation. Some container operations can make previously saved iterators unusable. For example, when a vector grows and reallocates storage, existing iterators can become invalid. Lists and sets have different rules. This means you cannot treat iterators as permanently stable references unless you know the guarantees of the specific container and operation.
The safe habit is simple: after modifying a container structurally, do not assume old iterators remain valid unless the container’s rules clearly allow it.
Iterator vs Pointer in C++
Iterators often behave like pointers, but they are not always raw pointers. A pointer directly refers to memory. An iterator is a generalized traversal object that may wrap more complex logic depending on the container. Some iterators, such as vector iterators in simple implementations, may feel very pointer-like. Others, such as map iterators, work over node-based structures and are conceptually higher-level.
| Feature | Pointer | Iterator |
|---|---|---|
| Main role | Direct memory address access | Container traversal abstraction |
| Works with STL containers | Not as a universal abstraction | Yes |
| Supports all pointer arithmetic | Yes for raw arrays | Depends on iterator category |
| Container-specific behavior | No | Yes |
This is why iterators matter more than plain pointers in STL programming.
Iterator and Range-Based Loops
Range-based for loops are built on iterator concepts even though the syntax is shorter. When you write a loop such as for (int x : values), the compiler uses the container’s begin and end mechanisms behind the scenes. This means range-based loops are not an alternative to iterator logic so much as a cleaner surface form built on the same foundation.
This is important because understanding iterators helps you understand what range-based loops can and cannot do, and when explicit iterator control is still necessary.
Common Real-World Uses of Iterators
- Traversing containers in generic library code
- Defining ranges for STL algorithms
- Inserting or erasing at specific container positions
- Backward traversal with reverse iterators
- Safe read-only traversal with const iterators
These patterns appear so often in STL code that iterator literacy is essential for writing clean C++.
Common Mistakes with Iterators in C++
- Dereferencing
end(), which is not a valid element. - Using an iterator after container modification invalidated it.
- Assuming every iterator supports indexing or arithmetic.
- Forgetting the difference between const iterators and normal iterators.
- Using explicit iterators where a simple range-based loop would be clearer.
Most iterator bugs come from forgetting that iterator behavior depends on both the container and the iterator category.
Insert Iterators and Output Adapters
The STL also provides iterator adapters such as back_inserter, front_inserter, and inserter. These are especially useful with algorithms that write output into containers. Instead of manually looping and calling container insertion functions yourself, an algorithm can write through an iterator adapter and let the container grow naturally in the correct way.
Why Iterator Category Affects Algorithm Choice
One of the most important STL design rules is that algorithms assume certain iterator capabilities. A container may support traversal, but that does not automatically mean every algorithm can use it efficiently. Understanding iterator category helps explain why some algorithms feel universal while others are limited to containers with stronger traversal power.
Best Practices for Iterator in C++
- Use iterators when working with STL algorithms and explicit range logic.
- Prefer
const_iteratorwhen modification is not needed. - Use reverse iterators for backward traversal instead of manual index tricks when appropriate.
- Know the iterator invalidation rules of the container you are using.
- Use range-based loops when they express the intent more clearly than explicit iterator code.
These habits make iterator-based code safer and easier to read.
Important Rules to Remember About Iterator in C++
- Iterators are generalized pointer-like objects for container traversal.
- Most STL algorithms work on iterator ranges instead of directly on containers.
begin()points to the first element andend()points past the last element.- Different containers provide different iterator categories and strengths.
- Iterator validity can change after container modifications.
Continue learning C++ in order
Follow the topic sequence with the previous and next lesson.