Iterators In STL

By Sruthy

By Sruthy

Sruthy, with her 10+ years of experience, is a dynamic professional who seamlessly blends her creative soul with technical prowess. With a Technical Degree in Graphics Design and Communications and a Bachelor’s Degree in Electronics and Communication, she brings a unique combination of artistic flair…

Learn about our editorial policies.
Updated March 10, 2024

A Complete Overview Of Iterators In STL.

In this tutorial, we will look into the details of iterators, their types, advantages, and the various functions they support.

What is an Iterator? In general, an iterator is just like any object that points to a particular element in a range of data like an array or a container. An iterator is just like a pointer in C.

=> Look For The Entire C++ Training Series Here.

ITERATORS IN STL

Overview

In STL, an iterator is an object that can be used to traverse through or step through the elements in the container by using a set of operators like increment operator (++) or dereference operator (*).

Iterators are crucial in STL programming as they play an important role in connecting the algorithms to the container in addition to accessing and manipulating the data stored inside the containers.

Types Of Iterators

Depending on the functionality implemented by the iterators, they are classified as follows:

Types of Iterators

  • Input and Output Iterators: These are the most simplified types of iterators. They are most useful in sequential input-output operations containing single-pass.
  • Forward Iterators: These are just like input iterators but have a direction i.e. forward direction in the sense they can be used to traverse through a range in the forwarding direction. When forward iterators are not constant they can also be used as output iterators. Most standard STL containers at least support forward iterators.
  • Bidirectional Iterators: These are similar to forward iterators with the only difference that they are bidirectional. This means that we can use these bidirectional iterators to traverse through the range in the forward as well as backward direction.
  • Random Access Iterators: Random access iterators are most powerful among all the iterators. These are non-sequential iterators. Random-access iterators allow us to access any random value by applying an offset to the current value without having to pass through each element sequentially. They exhibit similar properties like Pointers in C.

One thing to note is that not all STL containers support all the iterators. Different containers support different iterators depending on the requirement of their functionality.

Below is the list of containers that use different iterators:

ContainersIterators
StackNo iterator
QueueNo iterator
Priority QueueNo iterator
ListBidirectional
VectorRandom-Access
DequeRandom-Access
MapBidirectional
MultimapBidirectional
SetBidirectional
MultisetBidirectional

Advantages Of Iterators

Iterators are extremely useful especially while programming using different ranges and containers.

Some of the advantages of using iterators in programming can be summarized below:

#1) Code Reusability

As long as we use iterators to access elements in our program, we can just change the name of the container in our iterator definition and use the rest of the code in a similar way whenever we need to change the container.

This is especially useful in scenarios where we plan to replace a vector container using a list container. If in place of iterators we were using [] operator, the code to access elements would be useless when we change the containers.

#2) Ease And Convenience Of Programming

Iterators come with various in-built functions that aid us in traversing and accessing the contents of the container easily and conveniently.

For Example, we need not keep on checking the end of the list or array-like we have to do while using [] operators and we need to alter the program code like when we want to add elements, and we need to change them for a loop.

When using iterators we can directly access begin () and end () functions of the iterators without having to keep a tab on when we reach the end of the list and also we need not change them for a loop.

#3) Dynamic Add/Remove

While using iterators we can easily and dynamically add or remove the elements in the container without having to shift the elements like we have to do in [] operators.

Let’s demonstrate this with the following Example:

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

int main()
{
   vector<int> vec1 = { 1, 1, 2 };
   
  // Declaring an iterator
   vector<int>::iterator i;
   // Inserting element
   for (i = vec1.begin(); i != vec1.end(); ++i) {
     if (i == vec1.begin()) {
        i = vec1.insert(i, 3); // insert 3 at the beginning of vec1
      }
}
// contents of vec1 3 1 1 2
cout<<"Vector contents after addition";
cout<<endl;
for (i = vec1.begin(); i != vec1.end(); ++i) {
   cout << *i << " ";
}
cout<<endl;
for (i = vec1.begin(); i != vec1.end(); ++i) {
   if (i == vec1.begin() + 1) {
      i = vec1.erase(i); //this deletes 2nd element
     }
}
cout<<"Vector contents after deletion";
cout<<endl;
for (i = vec1.begin(); i != vec1.end(); ++i) {
   cout << *i << " ";
}
cout<<endl;
return 0;
}

Output:

Vector contents after addition
3 1 1 2
Vector contents after deletion
3 1 2

As seen in the above example, we see that using iterators we can easily add or remove elements from a container (vector in this case), without having to resort to the complex programming of shifting elements and restructuring the container.

Iterator Functions

As iterators itself are built-in constructs, they support various operations that can be done on iterator objects. These operations/functions allow us to efficiently traverse through the range and also manipulate the elements inside the container.

Now we will see a few major operations that iterators support.

  • begin: Returns the first or beginning position of the iterator.
  • end: Returns the last position or ‘after end’ position of the iterator.
  • prev: Returns the new iterator after decrementing the number of positions given in the argument.
  • next: Returns new iterator after advancing or incrementing the number of positions given in the argument.
  • inserter: Inserts element at any given position in a container.
  • advance: Increments the iterator position to the specified number given in the argument.

We will demonstrate the use of some of this function/operation in the following program:

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

int main()
{
   vector<int> v = { 1, 1,2,3,5 };
     // declaring iterators to a vector
   vector<int>::iterator itr1 = v.begin();
   vector<int>::iterator itr2 = v.end();
   
  auto it = next(itr1, 2);
    // displaying iterator position
   cout << "Using next() the new iterator is at: ";
   cout << *it << " ";
   cout << endl;
   
  auto it1 = prev(itr2, 2);
    // displaying iterator position
   cout << "The position of new iterator using prev() is: ";
   cout << *it1 << " ";
   cout << endl;
    
     //advance
   advance(itr1,3);
    // displaying iterator position
   cout << "After advance operation,itr1 is positioned at: ";
   cout << *itr1 << " ";
   cout << endl;
   return 0;
}

Output:

Using next() the new iterator is at: 2
The position of new iterator using prev() is: 3
After the advance operation,itr1 is positioned at: 3

Using the above program we have demonstrated the use of various iterator operations.

Conclusion

Thus we have come to the end of this tutorial on Iterators.

So far we have discussed the basics of STL, from our next tutorial onwards we will begin with STL containers and their programming.

=> Check Complete C++ FREE Training Series Here.

Was this helpful?

Thanks for your feedback!

Leave a Comment