Open In App

Iterators in C++ STL

Last Updated : 24 Oct, 2024
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Save
Share
Report
News Follow

An iterator in C++ is a pointer-like object that points to an element of the STL container. They are generally used to loop through the contents of the STL container in C++. The main advantage of STL iterators is that they make the STL algorithms independent of the type of container used. We can just pass the iterator to the container elements instead of the container itself to the STL algorithms.

In this article, we will learn about iterators in C++, their types, and how to use them.

Iterator Declaration

Each container in C++ STL has its own iterator. So, we have to declare an iterator as:

<type>::iterator it;

where,

  • type: Type of container for which the iterator is declared.
  • it: Name assigned to iterator object.

We can then initialize it by assigning some valid iterator. If we already have an iterator to be assigned at the time of delcaration, then we can skip the type declaration using the auto keyword.

auto it = iter

where, iter is the iterator assigned to the newly created it iterator.

Our C++ Course covers the use of iterators in the STL, ensuring you understand how to traverse different container types.

Example of Iterators

The below program illustrates how to use the iterator to traverse the vector container:

C++
// C++ program to show how to use iterator to
// traverse vector container
#include <bits/stdc++.h>
using namespace std;
int main() {
    vector<int> arr = {1, 2, 3, 4, 5};

    // Defining an iterator pointing to
    // the beginning of the vector
    vector<int>::iterator first =
      arr.begin();

    // Defining an iterator pointing to the
      // end of the vector
    vector<int>::iterator last =
      arr.end();
  
      // Iterating the whole vector
      while(first != last) {
      cout << *first << " ";
      first++;
    }

    return 0;
}

Output
1 2 3 4 5 

As you may have noticed, we have used vector::begin() and vector::end() function. These functions are the member functions to std::vector that returns the iterator to the first and one element after the last element of the vector. We use the iterators return be these functions to iterate the vectors.

Container Iterator Functions

C++ STL provides some member functions in STL container that return the iterators to at least the first and the last element. These member methods are defined in almost all of the STL container (leaving some limited access containers like stack, queue) with the same name for consistency.

The following table lists all methods that returns the iterator to the containers:

Iterator Function

Return Value

begin()

Returns an iterator to the beginning of container.

end()

Returns an iterator to the theoretical element just after the last element of the container.

cbegin()

Returns a constant iterator to the beginning of container. A constant iterator cannot modify the value of the element it is pointing to.

cend()

Returns a constant iterator to the theoretical element just after the last element of the container.

rbegin()

Returns a reverse iterator to the beginning of container.

rend()

Returns a reverse iterator to the theoretical element just after the last element of the container.

crbegin()

Returns a constant reverse iterator to the beginning of container.

crend()

Returns a constant reverse iterator to the theoretical element just after the last element of the container.

For Example, if vec is the name of the vector, then we can use the above methods as shown below:

vec.begin(), vec.rbegin(), vec.cbegin(), vec.crbegin()

vec.end(), vec.rend(), vec.cend(), vec.crend()

Iterators Operations

Just like pointer arithmetic, there are some operations that are allowed on C++ iterators. They are used to provide different functionalities that increases the importance of iterators. There are 5 valid iterator operations in C++:

  • Dereferencing Iterators
  • Incrementing/Decrementing Iterators
  • Adding/Subtracting Integer to Iterators
  • Subtracting Another Iterator
  • Comparing Iterators

Dereferencing Iterators

Dereferencing operation allows the users to access or update the value of the element pointed by the iterator. We use the (*) indirection operator to dereference iterators just like pointers.

Syntax

*it; // Access
*it = new_val; // Update

where new_val is the new value assigned to the element pointed by iterator it.

Incrementing/Decrementing Iterators

We can increment or decrement the iterator by 1 using (++) or (–) operators respectively. Increment operation moves the iterator to the next element in the container while the decrement operation moves the iterator to the previous element.

Syntax

it++; // post-increment
++it; // pre-increment

it–; // post-decrement
it; // pre-decrement

Adding/Subtracting Integer to Iterators

We can also add or subtract an integer value from the iterators. It will more the iterator next or previous position according to the added integer value.

Syntax

it + int_val; // Addition

it int_val; // Subtraction

where int_val is the integer values that is being added or subtracted from the iterator it.

Subtracting Another Iterator

We can subtract one iterator from another to find the distance (or the number of elements) between the memory they are pointing to.

Syntax

it1 it2

Comparing Iterators

We can also test the two iterators of the same type against each other to find the relationship between them. We can use the relational operators like (==) equality and (!=) inequality operators along with other relational operators such as <, >, <=, >=.

Syntax

it1 != it2 // Equal to
it1 == it2 // Not equal to

it1 > it2 // Greater than
it1 < it2 // Less than
it1 >= it2 // Greater than equal to
it1 <= it2 // Less than equal to

Types of Iterators in C++

STL iterators can be divided on the basis of the operations that can be performed on them. As such. there are 5 main types of iterators in C++ which as listed in the below table along with supported containers and supported iterator operations.

Iterator

Description

Supported Containers

Supported Operations

Input Iterator

It is a one-way iterator used to read the values.

Input Stream

Dereferencing, Increment, Equality

Output Iterator

It is also a one-way iterator but used to assign the values. It cannot access the values.

Output Stream

Dereferencing (write only), Increment

Forward Iterators

It can access and as well as assign the values. It is the combination of both input and output iterator.

forward_list, unordered_map, unordered_set

Dereferencing, Increment, Equality

Bidirectional Iterators

It can move in both direction either in forward or backward. The containers like list, set, and multimap supports bidirectional iterators.

list, map, set, multimap, multiset

Dereferencing, Increment/Decrement, Equality

Random Access Iterators

Random-access iterators are iterators that can be used to access elements at distance from the element they point to, offering the same functionality as pointers.

vector, deque, array, string

All

As we may have noticed from the above table, apart from the input and output iterators, as we go down the table, the iterator type contains the features of above iterator along with some new features.

Iterator Adaptors

Iterator adaptors in C++ are the special type of iterators that are built over traditional iterators to provide specialized functionality. There are many iterator adaptors in C++ some of which are given below:

Iterator Adaptors Type

Description

Reverse Iterator

The reverse iterator is built over bidirectional or above type of operator and allows users to traverse the container in the reverse direction.

Stream Iterators

The stream iterators namely, istream and ostream iterators are built on the input and output iterators respectively. These iterators allow the users to use the streams as containers.

Move Iterators

Move iterators are used to introduce the move semantics in STL algorithms. The move iterators move the ownership of the copied container data to the copying container without creating the extra copies.

Inserter Iterator

The insertor iterators allows you to insert the given elements at some position in the container. There are three insertor iterators in C++:

  1. back_insert_iterator: Inserts at the back of the container.
  2. front_insert_iterator: Inserts at the front of the container.
  3. insert_iterator: Inserts at anywhere in the container.

These iterators can be created using back_inserter(), front_inserter(), inserter() functions in C++.

Iterator Utility Functions in C++

C++ STL provide the various function to simplify the working with iterators. They are listed in the below table:

FunctionDescriptionSyntax
std::advanceAdvances an iterator by a specific number of positions.advance(it, n)
std::nextReturns the iterator that is a specified number of positions ahead of the given iterator.next(it, n)
std::prevReturns the iterator that is a specified number of positions behind the given iterator.prev(it, n)
std::distanceReturns the number of elements between two iterators.distance(it1, it2)
std::beginReturns an iterator to the first element of the given container.begin(container)
std::endReturns an iterator to the element following the last element of the given container.end(container)
std::rbeginReturns a reverse iterator to the last element of the given container.rbegin(container)
std::rendReturns a reverse iterator to the element preceding the first element of the given container.rend(container)
std::inserterCreates an insert iterator that inserts elements into a container at a specified position.inserter(container, position)
std::back_inserterCreates a back insert iterator that appends elements to the end of a container.back_inserter(container)
std::front_inserterCreates a front insert iterator that inserts elements at the front of a container.front_inserter(container)

Applications of Iterators with Examples

Iterators are extensively used in C++ for many different purposes while working with STL containers and algorithms. Following are some primary applications of iterators in C++ which their code examples:

Traversing Containers

Traversing STL containers is the most basic application of iterators. In this, we use the begin() and end() functions to get the begin and end iterators to traverse the whole container. Basically, we keep incrementing the begin iterator till it is not equal to the end.

Example

C++
// C++ program to show how to use iterator to
// traverse set container
#include <bits/stdc++.h>
using namespace std;

int main() {
    set<int> s = {10, 20, 30, 40, 50};

    // Iterator to the beginning of the set
    auto it = s.begin();

    // Iterating through the entire set
    while (it != s.end()) {
      
          // Dereferencing iterator to access value
        cout << *it << " ";
      
          // Incrementing the iterator
        it++;
    }

    return 0;
}

Output
10 20 30 40 50 

Just like that, any container can be traversed.

Reversing a Container

Reverse iterators allow you to traverse a container from the end to the beginning without needing to manually handling the reversal.

Example

C++
// C++ program to show how to use reverse iterators
// to traverse a container from end to beginning
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> vec = {10, 20, 30, 40, 50};

    // Defining reverse iterators pointing to the
      // reverse beginning of vec
    auto it = vec.rbegin();

    // Iterating the whole vector in reverse
    while (it != vec.rend()) {
        cout << *it << " ";
        it++;
    }

    return 0;
}

Output
50 40 30 20 10 

Container-Independent Algorithms

Iterators allow algorithms to work with any container type, making functions like std::sort(), std::find(), and std::for_each() more flexible. You can pass iterators instead of the actual container.

Example

C++
// C++ program to show how algorithms can work
// with iterators of any container type
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> vec = {30, 10, 40, 10, 50};
      multiset<int> ms = {10, 30, 10, 20, 40, 10};

    // Using the std::count() algorithm to count
      // the number of occurences of 10 in vector
      // and multiset using iterator
      cout << "10s in Vector: " << count(vec.begin(),
                                vec.end(), 10) << endl;
      cout << "10s in Multiset: " << count(ms.begin(),
                                  ms.end(), 10);

    return 0;
}

Output
10s in Vector: 2
10s in Multiset: 3

Additional Applications of Iterators

There are more applications of STL iterators:

  • Distance Calculation: Using std::distance(), iterators help calculate the number of elements between two positions in a container.
  • Stream Iteration: Stream iterators allow you to treat input/output streams like containers, making it easier to read from and write to streams using STL algorithms.
  • Move Semantics in STL Algorithms: Move iterators introduces the move semantics in STL algorithms which helps in increasing performance and efficiency by avoiding unnecessary copying. The data will be moved according to the rules of move semantics.
  • Custom Iterators for Data Structures: Custom iterators can be implemented for non-STL data structures like trees or graphs to provide the support for STL algorithms and many other features. We may need to follow a few set of rules and conventions to provide proper incrementing, decrementing, and other operations.

Iterators in C++ STL – FAQs

What is the difference between iterators and pointers in C++?

Iterators works similarly to pointers but provide a more generalized way to access elements in a container. Unlike raw pointers, iterators are designed to work with a wide variety of data structures (e.g., vectors, lists) and provide additional operations, such as the ability to traverse and manipulate containers in specific ways (forward, reverse, or bidirectionally).

Why does C++ have both cbegin() and begin()?

cbegin() returns a constant iterator, ensuring that the container’s elements cannot be modified during iteration. This is useful when you need to ensure read-only access.

Why do we need the std::advance() function?

std::advance() abstracts the logic for advancing an iterator by a specific number of steps. This is especially helpful for iterator types that do not support random access, like bidirectional iterators where we have to manually increment the iterator given number of times.

Why use iterator adaptors like back_inserter()?

Iterator adaptors, such as back_inserter(), allow for specialized functionality, like appending elements to a container without manually managing the container’s size or position.



Previous Article
Next Article

Similar Reads

Erase Range of Elements From List Using Iterators in C++ STL
Prerequisites:List in C++Iterators in C++ A list is a type of container which requires the same properties as a doubly linked list. We can insert elements from either side of the list, but accessing elements with an index is not possible in the list. So, removing elements from the list is not an easy task. But, we have a method to remove multiple e
2 min read
Different types of range-based for loop iterators in C++
Range-Based 'for' loops have been included in the language since C++11. It automatically iterates (loops) over the iterable (container). This is very efficient when used with the standard library container (as will be used in this article) as there will be no wrong access to memory outside the scope of the iterable. The loop will automatically star
5 min read
Random Access Iterators in C++
After going through the template definition of various STL algorithms like std::nth_element, std::sort, you must have found their template definition consisting of objects of type Random-access Iterator. So what are they and why are they used?Random-access iterators are one of the five main types of iterators present in C++ Standard Library, others
6 min read
Forward Iterators in C++
After going through the template definition of various STL algorithms like std::search, std::search_n, std::lower_bound, you must have found their template definition consisting of objects of type Forward Iterator. So what are they and why are they used ? Forward iterators are one of the five main types of iterators present in C++ Standard Library,
6 min read
Difference between Iterators and Pointers in C++ with Examples
In C++ programming, we have both pointers and iterators that are used in managing and manipulating data structures. There are many similarities between iterators and pointers in their ability to reference and dereference memory, but there are certain differences between the two. Understanding the difference is very important in C++ programming. Poi
4 min read
Introduction to Iterators in C++
An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualized as something similar to a pointer pointing to some location and we can access the content at that particular location using them. Iterators play a critical role in conne
6 min read
Bidirectional Iterators in C++
After going through the template definition of various STL algorithms like std::reverse, std::next_permutation and std::reverse_copy you must have found their template definition consisting of objects of type Bidirectional Iterator. So what are they and why are they used ? Bidirectional iterators are one of the five main types of iterators present
7 min read
Why Use Iterators Instead of Array Indices?
In C++, both iterators and array indices are used to access and manipulate elements in a container, such as arrays, vectors, and lists. However, one common question that arises is why should we prefer using iterators over array indices in certain scenarios? In this article, we will learn the advantages of using iterators over array indices, and pro
3 min read
Output Iterators in C++
After going through the template definition of various STL algorithms like std::copy, std::move, std::transform, you must have found their template definition consisting of objects of type Output Iterator. So what are they and why are they used ? Output iterators are one of the five main types of iterators present in C++ Standard Library, others be
6 min read
Input Iterators in C++
After going through the template definition of various STL algorithms like std::find, std::equal, std::count, you must have found their template definition consisting of objects of type Input Iterator. So what are they and why are they used?Input iterators are one of the five main types of iterators present in the C++ Standard Library, others being
6 min read
Iterators Operations in C++
Iterators are pointer like objects that are used to refer iterator the STL containers. Just like pointer arithmetic, there are some operations that are allowed on iterators in C++. They are used to provide different functionalities to make iterator more powerful and versatile. In this article, we will learn about iterator operations (also called it
9 min read
Rotate in C++ STL
The function is defined in header <algorithm>. It rotates the order of the elements in the range [first, last], in such a way that the element pointed by the middle becomes the new first element. Function Template : void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last) first, last : Forward Iterators to the initial
3 min read
deque::at() and deque::swap() in C++ STL
Deque or Double ended queues are sequence containers with the feature of expansion and contraction on both the ends. They are similar to vectors, but are more efficient in case of insertion and deletion of elements at the end, and also the beginning. Unlike vectors, contiguous storage allocation may not be guaranteed. deque::at()at() function is us
4 min read
list::push_front() and list::push_back() in C++ STL
Lists are containers used in C++ to store data in a non-contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::push_front() push_front() function is used to push elements into a list from the front. The n
4 min read
list::pop_front() and list::pop_back() in C++ STL
Lists are containers used in C++ to store data in a non contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::pop_front() pop_front() function is used to pop or remove elements from a list from the front
4 min read
list::front() and list::back() in C++ STL
Lists are containers used in C++ to store data in a non-contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::front() This function is used to reference the first element of the list container. This func
3 min read
list::empty() and list::size() in C++ STL
Lists are containers used in C++ to store data in a non contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::empty()empty() function is used to check if the list container is empty or not. Syntax : list
3 min read
list::remove() and list::remove_if() in C++ STL
Lists are containers used in C++ to store data in a non contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::remove() remove() function is used to remove all the values from the list that correspond to
3 min read
queue::empty() and queue::size() in C++ STL
Queue is a type of container adaptor that operate in a first in first out (FIFO) type of arrangement. Elements are inserted at the back (end) and are deleted from the front. queue::empty() empty() function is used to check if the queue container is empty or not. SyntaxqueueName.empty()ParametersThis function does not accept any parameter.Return Val
4 min read
deque::pop_front() and deque::pop_back() in C++ STL
Deque or Double ended queues are sequence containers with the feature of expansion and contraction on both the ends. They are similar to vectors, but are more efficient in case of insertion and deletion of elements at the end, and also the beginning. Unlike vectors, contiguous storage allocation may not be guaranteed. deque::pop_front() pop_front()
4 min read
queue::front() and queue::back() in C++ STL
Queue are a type of container adaptors which operate in a first in first out (FIFO) type of arrangement. Elements are inserted at the back (end) and are deleted from the front. queue::front() This function is used to reference the first or the oldest element of the queue container. This function can be used to fetch the first element of a queue.Syn
3 min read
forward_list::push_front() and forward_list::pop_front() in C++ STL
Forward list in STL implements singly linked list. Introduced from C++11, forward list are useful than other containers in insertion, removal and moving operations (like sort) and allows time constant insertion and removal of elements.It differs from list by the fact that forward list keeps track of location of only next element while list keeps tr
4 min read
map::clear() in C++ STL
Map is dictionary like data structure. It is an associative array of (key, value) pair, where only single value is associated with each unique key. map::clear() clear() function is used to remove all the elements from the map container and thus leaving it's size 0. Syntax: map1.clear() where map1 is the name of the map. Parameters: No parameters ar
2 min read
priority_queue::empty() and priority_queue::size() in C++ STL
Priority queues are a type of container adaptors, specifically designed such that the first element of the queue is either the greatest or the smallest of all elements in the queue. However, in C++ STL (by default) the largest element is at the top. We can also create a priority queue having the smallest element at the top by simply passing an extr
4 min read
priority_queue::top() in C++ STL
Priority queues are a type of container adaptors, specifically designed such that the first element of the queue is either the greatest or the smallest of all elements in the queue. In general, elements are arranged according to some priority. However in C++ STL, the top element is the greatest element by default. We can also make a priority queue
3 min read
array::front() and array::back() in C++ STL
Array classes are generally more efficient, light-weight, and reliable than C-style arrays. The introduction of array class from C++11 has offered a better alternative for C-style arrays. array::front() This function is used to reference the first element of the array container. This function can be used to fetch the first element of an array. Synt
3 min read
std::istream_iterator and std::ostream_iterator in C++ STL
The STL is a very powerful library in C++. It is strongly built on the principles of template programming. The STL library has three main components : Containers: These classes define the data structures which are used to contain the data. The data may be stored in linked lists, or trees or arrays. The containers provided in the STL are vector, deq
6 min read
deque::clear() and deque::erase() in C++ STL
Deque or Double-ended queues are sequence containers with the feature of expansion and contraction on both ends. They are similar to vectors, but are more efficient in the case of insertion and deletion of elements at the end, and also at the beginning. Unlike vectors, contiguous storage allocation may not be guaranteed. deque::clear() The clear()
5 min read
list::clear() in C++ STL
Lists are containers used in C++ to store data in a non contiguous fashion, Normally, Arrays and Vectors are contiguous in nature, therefore the insertion and deletion operations are costlier as compared to the insertion and deletion option in Lists. list::clear()clear() function is used to remove all the elements of the list container, thus making
1 min read
deque::operator= and deque::operator[] in C++ STL
Deque or Double ended queues are sequence containers with the feature of expansion and contraction on both the ends. They are similar to vectors, but are more efficient in case of insertion and deletion of elements at the end, and also the beginning. Unlike vectors, contiguous storage allocation may not be guaranteed. deque::operator= This operator
4 min read
Article Tags :
Practice Tags :
three90RightbarBannerImg