In this article, we’ll learn about Iterators in C++ in detail. While working with data elements, we often come across situations where we need to traverse through every element of the data structure. In order to serve the purpose, C++ provides us with Iterators.
Iterators are basically objects
which help programmers access the data items from the containers. It points at a particular index position(memory address) of the Standard Template Library container and enables to access the data item at that position.
Syntax:
1 |
container-name<data-type>::iterator iterator-name; |
Example:
1 |
list<int>::iterator A; |
Thus, iterators help us move and traverse through the items of the containers.
Types of Iterators in C++
At an initial stage, Iterators and Pointers may feel similar to you in terms of functionality. But by the end of this tutorial, you will get to know the differences between an Iterator and a Pointer in C++.
Iterators work in a different manner than pointers. The following are the type of iterators that serve different functionality altogether:
- Input Iterator
- Output Iterator
- Forward Iterator
- Bi-directional Iterator
- Random-Access Iterator
1. Input Iterator
An Input Iterator is a basic type of iterator which serves the sole purpose of traversing
the elements of a container.
It helps us move through the elements of the container but it does not provide us with the access to modify the data values of the container.
Following is the list of operators which can be used along with Input Iterators:
- Dereference Operator (*)
- Increment Operator (++)
- Equal to Operator (==)
- Not Equal to Operator (!=)
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <list> using namespace std; int main() { list<int> li= { 10, 20, 42, 50, 75 }; list<int>::iterator x; cout<<"Traversing elements of the list.."<<endl; for (x = li.begin(); x != li.end(); x++) { cout << (*x) << " "; } return 0; } |
In the above snippet of code, we have used a list as a container and declared ‘x‘ as the iterator to that list ‘li‘. The begin()
and end()
functions are used to point to the first and last position of the container. The iterator traverses the list in the forward (ascending) direction.
Output:
1 2 |
Traversing elements of the list.. 10 20 42 50 75 |
We will get to learn more about these operations in the coming section of this article.
2. Output Iterator
The Output Iterators are complementary
to the Input Iterators i.e. opposite
to each other in terms of functionality.
They can be used to assign and manipulate the values of the data items of the container. But, they cannot be used to access or traverse through the elements of a container.
Following is the list of operators which can be used along with Output Iterators:
- Dereference Operator (* , ->)
- Increment Operator (++)
- Equal to Operator (==)
- Not Equal to Operator (!=)
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <iostream> #include <list> using namespace std; int main() { list<int> li= { 10, 20, 42, 50, 75 }; list<int>::iterator x; cout<<"Traversing elements of the list.."<<endl; for (x = li.begin(); x != li.end(); x++) { //using output iterator to change or assign new values to all the // elements of the list *x = 4; } for (x = li.begin(); x != li.end(); x++) { //using input iterator to traverse the list cout << (*x) << " "; } return 0; } |
As seen above, we have assigned value = 4 to all the elements of the container using output iterator.
Output:
1 2 |
Traversing elements of the list.. 4 4 4 4 4 |
3. Bi-directional Iterator
Bi-directional Iterator is quite similar to an Input Iterator. The only difference is that a bi-directional iterator can traverse the elements in both the directions i.e. forward and backward(reverse) direction.
Following is the list of operators which can be used along with Input Iterators:
- Dereference Operator (* , ->)
- Increment Operator (++)
- Equal to Operator (==)
- Not Equal to Operator (!=)
- Decrement Operator (–)
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> #include <list> using namespace std; int main() { list<int> li= { 10, 20, 42, 50, 75 }; list<int>::iterator x; cout<<"Traversing elements of the list in forward direction.."<<endl; for (x = li.begin(); x != li.end(); x++) { //using input iterator to traverse the list cout << (*x) << " "; } cout<<endl; cout<<"Traversing elements of the list in backward direction.."<<endl; for (x=li.end();x!=li.begin();--x) { if (x != li.end()) { cout << (*x) << " "; } } cout << (*x); return 0; } |
Output:
1 2 3 4 |
Traversing elements of the list in forward direction.. 10 20 42 50 75 Traversing elements of the list in backward direction.. 75 50 42 20 10 |
4. Forward Iterator
Forward Iterator can be termed as a combination of Input and Output Iterator respectively. It allows us to modify
the values of the data items of the containers as well as traverse
through the elements of the container.
But, unlike Bi-directional Iterator, the Forward Iterator does not permit the traversal of elements in a reverse or backward direction.
Following is the list of operators which can be used along with Input Iterators:
- Dereference Operator (* , ->)
- Increment Operator (++)
- Equal to Operator (==)
- Not Equal to Operator (!=)
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> #include <list> using namespace std; int main() { list<int> li= { 10, 20, 42, 50, 75 }; list<int>::iterator x; cout<<"Traversing elements of the list.."<<endl; for (x = li.begin(); x != li.end(); ++x) { cout << (*x) << " "; //using input iterator to traverse the list } for (x = li.begin(); x != li.end(); x++) { // using output iterator to change or assign new values to all the // elements of the list *x = 4; } cout<<endl; cout<<"Traversing elements of the list after assigning a new value to the list.."<<endl; for (x = li.begin(); x != li.end(); ++x) { cout << (*x) << " "; //using input iterator to traverse the list } return 0; } |
Output:
1 2 3 4 |
Traversing elements of the list.. 10 20 42 50 75 Traversing elements of the list after assigning a new value to the list.. 4 4 4 4 4 |
5. Random-Access Iterator
Random-Access Iterators enable the users to access the data items at any random index/position in the container. Moreover, it contains all the properties of a Bi-directional container.
Further, Random-Access Iterators have access to pointer subtraction and addition for the sake of random access to the data items.
Operations performed by Iterators in C++
The following are some of the basic and most frequently used functions to manipulate data items through iterators:
begin()
: This method returns the starting/beginning index of the data items in the container.end()
: It returns the ending index of the data items in the container.prev(int)
: Returns a new iterator that points to the data item which is present ahead of the position mentioned in the function parameter.next(int)
: It returns a new iterator that points to the data item which is present after the position mentioned in the function parameter.inserter(container, int)
: This function adds/inserts a value at the specified index or position in the container.advance(int)
: It increments by the number specified in the parameter and points to the data element specified at that index.
Example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#include <iostream> #include <list> using namespace std; int main() { list<int> li= {10, 20, 42, 50, 75}; list<int>::iterator x; cout<<"Traversing elements of the list in forward direction.."<<endl; for (x = li.begin(); x != li.end(); x++) { cout << (*x) << " "; //using input iterator to traverse the list } cout<<endl; list<int>::iterator ee = li.begin(); advance(ee, 3); cout << "The element pointed by the iterator after using advance(): "; cout << *ee << " "; cout<<endl; list<int>::iterator A = li.begin(); list<int>::iterator B = li.end(); auto aa = next(A, 2); auto bb = prev(B, 2); cout << "Element pointed using next() is : "; cout << *aa << " "; cout << endl; cout << "Element pointed using prev() is : "; cout << *bb << " "; cout << endl; return 0; } |
Output:
1 2 3 4 5 |
Traversing elements of the list in forward direction.. 10 20 42 50 75 The element pointed by the iterator after using advance(): 50 Element pointed using next() is : 42 Element pointed using prev() is : 50 |
Advantages of Iterators in C++
Easy for programming
: With the help of iterators, we don’t need to keep an account of the varying size of the container and we can thus easily traverse through the container using begin() and end() methods.- High level of
re-usability of code
. Dynamically
add or remove data elements from the container.
Pointers vs Iterators in C++
Conclusion
Thus, in this article, we have understood the need, working and benefits of Iterators in C++ STL.