Practice
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Frontend UI Machine Coding
Resources
Career Advice and Roadmaps
Data Structures and Algorithms
Machine Coding Round (LLD)
System Design & Architecture (HLD)
Backend Development
Frontend Development
Project Ideas for Software Developers
Core Computer Science
Companies
SDE Jobs & Internships
Interview Questions
Compare Companies
IDE
Online IDE
Collaborative IDE

C++ STL: iterators (Complete Guide)

Divya Jain
Divya Jain

Iterators are one of the four pillars of the STL. They are very similar to pointers. Like pointers point to the memory address of the variable, iterators point to the memory locations of the elements of the STL containers.

They allow us to access the elements of the container. They reduce the complexity and execution time of the program. Algorithms in STL manipulate data using iterators. The type of container doesn't matter while using iterators, thus making it generic.

Declaring an iterator

Syntax:

container_type::iterator iterator_name;

Example:

vector < int > v;
vector < int > ::iterator itr; //creates an iterator itr to a vector of integers

Types of Iterators

According to functionality, iterators can be classified into five types. Let us discuss them one by one:

  1. Input Iterators: They are the least commonly used iterators and are mainly used for reading values from the container. They allow us to sequentially visit the data, such that no element can be accessed more than once. They don't allow us to modify the values of the container.
#include<iostream>
#include<vector>
using namespace std;

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

  for (itr = v.begin(); itr != v.end(); ++itr) {
    cout << ( * itr) << " ";
  }
  return 0;
}

Output

1 2 3 4 5 

2. Output iterators: They are the exact opposite of the output iterators. Just like input containers are used to read the elements of the container, output iterators are used to modify them. They are also a one-way iterator.

#include<iostream>
#include<vector>
using namespace std;

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

  for (itr = v.begin(); itr != v.end(); ++itr) {
    * itr = 100;
  }
  return 0;
}

3. Forward iterators: They are a combination of input and output iterators. They allow us both to access and modify the values of the container. Also, we can traverse the container only in the forward direction.

#include <iostream>
#include <vector>
using namespace std;

int main() {
  vector < int > v = { 1, 2, 3, 4, 5 };
  vector < int > ::iterator itr;
  for (itr = v.begin(); itr != v.end(); ++itr) {
    * itr = * itr + 10;
  }
  for (itr = v.begin(); itr != v.end(); ++itr) {
    cout << ( * itr) << " ";
  }
  return 0;
}

Output

11 12 13 14 15 

4. Bidirectional iterators: They are a replica of the forward iterators except for the fact that they allow us to move in both directions i.e support decrement operator.

#include<iostream>
#include<list>
using namespace std;

int main() {
  list < int > l = { 1, 2, 3, 4, 5 };
  list < int > ::iterator itr;
  for (itr = l.end(); itr != l.begin(); --itr) {
    if (itr != l.end()) {
      cout << ( * itr) << " ";
    }
  }
  cout << ( * itr);
  return 0;
}

Output

5 4 3 2 1

5. Random-Access Iterators: They provide us random access to the elements of the container. They are also called bi-directional with random access.

#include<iostream>
#include<vector>
using namespace std;

int main() {
  vector < int > v = { 1, 2, 3, 4, 5 };
  vector < int > ::iterator itr1;
  vector < int > ::iterator itr2;
  itr1 = v.begin();
  itr2 = v.end();
  if (itr1 < itr2) {
    cout << "Moving from begin to end\n";
    cout << "The number of elements are " << itr2 - itr1;
  }
  return 0;
}

Output

Moving from begin to end
The number of elements are 5

Operations on Iterators

  • begin(): It returns a bidirectional iterator pointing to the first element of the container. 
    Parameters: None
    Return value: iterator
     
  • end(): It returns a bidirectional iterator pointing past the last element of the container. 
    Parameters: None
    Return value: iterator
     
  • advance(itr, value): It increments the iterator by a certain value.
    Parameters: iterator, whose value needs to be incremented, integer value specifying by how much steps iterator should be advanced
    Return value: None
     
  • next(itr, value): It returns a new iterator that the iterator would point to after advancing the iterator value times.
    Parameters: iterator, whose value needs to be incremented, integer value specifying by how many steps iterator should be advanced
    Return value: iterator
     
  • prev(itr, value): It returns a new iterator that the iterator would point to after decrementing the iterator value times.
    Parameters: iterator, whose value needs to be decremented, integer value specifying by how many steps iterator should be decremented
    Return value: iterator
     
  • inserter(container, itr): It inserts the element at any position.
    Parameters: container in which element needs to be inserted, the position where element needs to be inserted
    Return type: None
#include<iostream>
#include<vector>
using namespace std;

int main() {
  vector < int > v = { 1, 2, 3, 4, 5 };
  vector < int > v2 = { 10, 20, 30 };
  vector < int > ::iterator itr = v.begin();
  cout << "The elements are: ";
  for (itr = v.begin(); itr < v.end(); itr++) {
    cout << * itr << ' ';
  }
  cout << '\n';
  itr = v.begin();
  advance(itr, 3);
  cout << "Iterator after advancing 3 steps: ";
  cout << * itr << '\n';
  vector < int > ::iterator it1 = prev(itr, 2);
  cout << "The position of prev iterator : ";
  cout << * it1 << '\n';
  vector < int > ::iterator it2 = next(itr, 1);
  cout << "The position of new iterator: ";
  cout << * it2 << '\n';
  copy(v2.begin(), v2.end(), inserter(v, itr));
  cout << "The new vector after inserting elements is : ";
  for (int & it: v)
    cout << it << " ";
  return 0;
}

Output

The elements are: 1 2 3 4 5 
Iterator after advancing 3 steps: 4
The position of prev iterator : 2
The position of new iterator: 5
The new vector after inserting elements is : 1 2 3 10 20 30 4 5 

Why use iterators?

  • They are easy and convenient to use.
  • They are generic.
  • They are efficient.
  • They help us to add or modify data dynamically.
Divya Jain
Divya Jain
Divya is an incoming SDE at Atlassian. She loves solving problems and web development. She loves to explore new things and is up for interesting conversations about tech.
SDE Bootcamp - Become a software engineer at a product-based company
Practice Data Structures & Algorithms
Learning Resources
Interview Prep Resources
Blog
  • Career Advice and Roadmaps
  • Data Structures & Algorithms
  • Machine Coding Round (LLD)
  • System Design & Architecture
  • Backend Development
  • Frontend Development
  • Awesome Project Ideas
  • Core Computer Science
Practice Questions
  • Machine Coding (LLD) Questions
  • System Design (HLD) Questions
  • Topic-wise DSA Questions
  • Company-wise DSA Questions
  • DSA Sheets (Curated Lists)
  • JavaScript Interview Questions
  • Frontend UI Machine Coding Questions
Online Compilers (IDE)
  • Online Java Compiler
  • Online C++ Compiler
  • Online C Compiler
  • Online Python Compiler
  • Online JavaScript Compiler
Topic-wise Problems
  • Dynamic Programming Interview Questions
  • Linked List Interview Questions
  • Graph Interview Questions
  • Backtracking Interview Questions
  • Arrays Interview Questions
  • Trees Interview Questions
Company-wise Problems
  • Amazon Interview Questions
  • Microsoft Interview Questions
  • Google Interview Questions
  • Flipkart Interview Questions
  • Adobe Interview Questions
  • Facebook Interview Questions
DSA Sheets (Curated Lists)
  • Top Interview Questions
  • FAANG Interview Questions
  • Most Asked Interview Questions
  • 6 month DSA Practice Sheet
  • 3 month DSA Practice Sheet
  • Last minute DSA Practice Sheet