Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🔴 Advanced  ·  Lesson 58

Iterators in C++ STL

In this lesson: What iterators are in C++ STL — begin(), end(), types and loops — with examples and output. In Hindi & English.

What is an iterator?

An iterator is an object that points to an element in a container and knows how to move to the next one. It behaves like a pointer:

  • *it — the element it points to
  • ++it — move to the next element
  • it == other — are they at the same position?

Iterators are the glue of the STL: containers hand out iterators, and algorithms like sort, find and reverse work on any pair of iterators. That is why the same algorithm works on a vector, a list or a deque.

begin() and end()

Every container has:

  • begin() — iterator to the first element
  • end() — iterator one past the last element
Text
 vector:  [ 78 | 91 | 66 | 84 ]
            ^                  ^
         begin()             end()   (past the last element)

The half-open range [begin, end) makes loops simple — stop when you reach end() — and an empty container has begin() == end().

Looping with an iterator

C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> marks = {78, 91, 66, 84};

    // explicit iterator type
    for (std::vector<int>::iterator it = marks.begin(); it != marks.end(); ++it) {
        *it += 2;                       // grace marks: modifies the element
    }

    // same thing with auto (C++11)
    for (auto it = marks.begin(); it != marks.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";

    // range-based for uses iterators behind the scenes
    for (int m : marks) std::cout << m << " ";
    std::cout << "\n";
    return 0;
}
80 93 68 86 80 93 68 86

A range-based for is the simplest choice when you just need every element. Use explicit iterators when you need the position, want to erase while looping, or pass a range to an algorithm.

The five iterator categories

CategoryCan doProvided by
InputRead once, move forward (*it, ++it)istream_iterator
OutputWrite once, move forwardostream_iterator, back_inserter
ForwardRead/write, move forward many timesforward_list, unordered_map
BidirectionalForward + move back (--it)list, set, map
Random-accessBidirectional + jump (it + 3, it[2], it2 - it1, <)vector, deque, array, plain pointers

Each category includes the abilities of the ones above it. An algorithm states the minimum it needs — std::sort requires random-access iterators, which is why list has its own list.sort().

const and reverse iterators

C++
#include <iostream>
#include <vector>

int main() {
    std::vector<int> v = {1, 2, 3, 4, 5};

    for (auto it = v.cbegin(); it != v.cend(); ++it) {   // const_iterator
        std::cout << *it << " ";        // *it = 9; would not compile
    }
    std::cout << "\n";

    for (auto it = v.rbegin(); it != v.rend(); ++it) {   // reverse_iterator
        std::cout << *it << " ";
    }
    std::cout << "\n";
    return 0;
}
1 2 3 4 5 5 4 3 2 1

Use cbegin()/cend() when you only read, so the compiler stops accidental changes. rbegin()/rend() walk backwards.

Useful iterator functions

FunctionMeaning
std::next(it, n)Iterator n steps ahead (default 1)
std::prev(it, n)Iterator n steps back
std::advance(it, n)Move it itself by n
std::distance(a, b)Number of steps from a to b

These work for every category, even list, where it + 3 is not allowed.

C++
std::vector<int> v = {10, 20, 30, 40};
auto it = std::find(v.begin(), v.end(), 30);
std::cout << "index = " << std::distance(v.begin(), it) << "\n";   // 2
std::cout << "last  = " << *std::prev(v.end()) << "\n";            // 40

Iterators over a map

A map iterator points to a pair: ->first is the key and ->second is the value.

C++
std::map<std::string, int> marks = {{"Aman", 78}, {"Priya", 91}};
for (auto it = marks.begin(); it != marks.end(); ++it) {
    std::cout << it->first << ": " << it->second << "\n";
}

Iterator invalidation

Changing a container can make existing iterators invalid (dangling):

ContainerOperationIterators that become invalid
vectorpush_back, insert (with reallocation)All
vectoreraseAt and after the erased element
dequeInsert at either endAll iterators (references stay valid)
list, set, maperaseOnly the erased element's iterator

Safe way to erase while looping — use the iterator that erase returns:

C++
std::vector<int> marks = {35, 20, 50, 12, 40};
for (auto it = marks.begin(); it != marks.end(); ) {
    if (*it < 33) it = marks.erase(it);   // erase returns the next valid iterator
    else ++it;
}
// marks: 35 50 40

(For vectors the idiomatic one-liner is std::erase_if(marks, [](int m){ return m < 33; }); in C++20.)

Common mistakes

  • Dereferencing end() or an iterator from an empty container.
  • Comparing iterators from two different containers.
  • Using it + 1 on a list or map iterator — use std::next(it).
  • Keeping an iterator after push_back on a vector.
  • Writing it++ inside erase loops incorrectly and skipping elements.
🏋️ Practice

Fill a list<int> with 10 numbers. Using only iterators, print it forwards and backwards, find the first number greater than 50 with std::find_if, print its position with std::distance, and erase every even number safely.

Summary

  • An iterator points to an element and moves through a container like a pointer.
  • begin() is the first element; end() is one past the last — never dereference it.
  • Categories: input, output, forward, bidirectional, random-access.
  • cbegin/cend for read-only, rbegin/rend for reverse.
  • Modifying a container can invalidate iterators; use the iterator returned by erase.

Related: STL introduction, vector, algorithms, list and deque.

Frequently Asked Questions

What is an iterator in C++?
An iterator is an object that points to an element inside a container and can move to the next element. It works like a generalised pointer: *it gives the element, ++it moves forward, and comparing with end() tells you when to stop. Algorithms such as sort and find take iterators to know which range to work on.
What does end() return in C++?
end() returns an iterator to the position just after the last element, not to the last element itself. It marks where a range stops. Dereferencing end() is undefined behaviour; to reach the last element use std::prev(v.end()) or v.back().
What are the types of iterators in C++?
The classic categories are input, output, forward, bidirectional and random-access iterators. vector and deque give random-access iterators (it + 5 works), list, set and map give bidirectional iterators (only ++ and --), and stream iterators are input or output iterators.
What is iterator invalidation?
An iterator becomes invalid when the container changes in a way that moves or removes the element it points to. For a vector, push_back may reallocate memory and invalidate all iterators, and erase invalidates iterators at and after the erased position. Using an invalid iterator is undefined behaviour.
← Back to C++ Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicSTL Algorithms Your progress: 58 / 81 (72%) · Lesson 59 / 81 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free