HOWTO · C++
How to Iterate Through a C++ std::list
Learn how to traverse a C++ std::list with an iterator, read or edit elements, and stop safely at end().
On this page
To traverse a std::list in C++, initialize an iterator with begin(), continue while it differs from end(), and increment it after processing each element. Dereference the iterator to read or change the current value. The loop stops before end(), which is a past-the-end marker rather than an iterator to the last element.
What Is std::list in C++?
std::list is the C++ Standard Library’s doubly linked list container. Its elements are stored in nodes that are linked to neighboring nodes, so they do not occupy one contiguous memory block as elements in a std::vector or array do. This structure supports traversal in both directions and allows insertion or removal at a position in constant time when you already have an iterator to that position.
A list does not provide direct indexing such as items[4]. Reaching an element by position requires advancing an iterator through the list, which takes time proportional to the distance traveled. Each element also needs link storage in addition to its value. Choose std::list when stable iterators and insertion or removal at known positions are useful; a vector is often simpler when you need compact storage or frequent indexed access.
C++ also provides std::forward_list, a separate singly linked container that supports forward traversal only. It is not the same container as std::list. For more background, see the doubly linked list article.
How to Iterate Through a std::list in C++
The iterator returned by begin() refers to the first element. end() refers just beyond the last element, so it is used as the loop’s stopping condition and must not be dereferenced. Incrementing the iterator advances it to the next element.
Run this example:
#include <iostream>
#include <list>
int main() {
std::list<int> scores{12, 18, 25};
for (std::list<int>::iterator it = scores.begin(); it != scores.end(); ++it) {
std::cout << *it << '\n';
}
}
12
18
25
Here, it starts at scores.begin(). Each pass reads the current value with *it, then ++it advances to the next node. When the iterator reaches scores.end(), the condition is false and the loop finishes without reading the past-the-end position.
You can edit an element through a non-const iterator by assigning to *it. For example, in the loop body, *it += 1; increases the current value. Use a range-based for loop when you only need to visit values: for (int score : scores). To change values in that form, bind each item by reference: for (int& score : scores). Use the explicit iterator loop when the iterator itself is needed, such as when removing an element at the current position.
When erasing during traversal, assign the iterator returned by erase to continue at the next element. Erasing invalidates the iterator to that element, while iterators to other std::list elements remain valid.