What are Iterators in C++?
C++ Iterator is one of the four foundations of the C++ STL, also known as the Standard Template Library. The memory address of the STL container classes is addressed through an iterator. To a certain extent, you can link them with a pointer for easier understanding.
C++ Iterator links algorithms and STL containers, enabling the alteration of the data contained inside. To get the desired outcome, you may use them to iterate over the container, access and assign the values, and execute various operators on them.
In C++, Based on their functionality, C++ Iterators are divided into 5 broad groups. An in-depth discussion of the following 5 iterators is included in this article:
- Input Iterators
- Output Iterators
- Forward Iterators
- Bidirectional Iterators
- Random Access Iterators
Introduction
C++ Iterators are objects (similar to pointers) that point to elements inside containers. To go through the contents of the container, we can use iterators. They can be imagined as something like a pointer pointing to a certain location, and we can use them to access the data at that specific location. Iterators are required to connect algorithms with containers and manipulate the data contained in those containers. A pointer is the most common indicator of an iterator. Using the increment operator (++), a pointer can iterate through the elements of an array. However, not all C++ iterators perform in a fashion that is comparable to that of pointers.
As illustrated in the image below, C++ Iterator can be divided into five groups based on functionality. The outer category is the most functionally powerful, and the inner category is the least functionally strong.
Characteristics of Iterators
The abilities of iterators include accessing, reading, writing, and iterating through container items. However, not all iterators have every property. The C++ iterators are shown in the following table, along with the properties each possesses.
Iterators | Characteristics | |||
---|---|---|---|---|
Access | Read | Write | Iterate | |
Input | -> | = *i | ++ | |
Output | *i= | ++ | ||
Forward | -> | = *i | *i= | ++ |
Bidirectional | = *i | *i= | ++, - - | |
Random Access | ->, [ ] | = *i | *i= | ++, - - |
Advantages of Iterators
C++ Iterators are very useful in some areas. Below are a few of these advantages:
Key | Description |
---|---|
Programming convenience | Iterators make it easy and convenient for you to write code. For instance, you don't have to be concerned about container size while using iterators. The end() method makes it simple to loop through the container and retrieve the final piece. Even the container's components can be changed without manually moving or performing all the work. |
Code Reusability | Without an iterator, converting the vector into a list without altering the code would not be feasible. However, since you are using an iterator, you can modify the vector's declaration to a list, which will still run effectively. You can reuse your code in this approach. |
Dynamic Processing | You may both dynamically allocate and destroy memory with the use of iterators. The dynamic processing of containers stops memory from being wasted. You can easily change the container sizes to meet your needs and specifications. |
Disadvantages of Iterators
C++ Iterator has some disadvantages as well. The following list includes a few of these drawbacks:
- It is impossible to move simultaneously from one data structure to another. In that case, the iterator won't work.
- Due to how iterators operate, we can not return once we start traversing elements.
- If you use an iterator to traverse over the STL container, its structure cannot be modified while traversing it.
Syntax of Defining Iterators
The syntax of iterators is shown below, where parameters are included. The C++ iterator declared type of container is specified by the <Container_Type> parameter.
- <Container_Type> :: iterator;
- <Container_Type> :: const_iterator;
All STL containers do not support all 5 types of C++ iterators. For example, the container "vector" supports random-access iterators while the container list supports bidirectional iterators.
The STL containers that they support in C++ are listed in the following table:
STL CONTAINER | ITERATOR SUPPORTED |
---|---|
Vector | Random-Access |
List | Bidirectional |
Dequeue | Random-Access |
Map | Bidirectional |
Multimap | Bidirectional |
Set | Bidirectional |
Multiset | Bidirectional |
Stack | Does not support any iterator |
Queue | Does not support any iterator |
Priority-Queue | Does not support any iterator |
Operations Performed on Iterators
The operators and operations applied to the C++ iterator are listed below.
Operator | Operations Performed on the Iterators |
---|---|
* | The element of the current position pointed by the iterator is returned by the * operator. |
++ | The iterator is increased by one using the "++" operator. As a result, an iterator points to the container's succeeding element. |
!= | Not equal to operators. Identify whether or whether the two iterators point to the same location. |
== | Equal to operators Identify whether the two iterators point to the same location. |
= | The iterator is assigned using the '=' operator. |
Types of Iterators
We can differentiate the C++ iterators into five categories.
- Input Iterators
- Output Iterators
- Forward Iterators
- Bidirectional Iterators
- Random Access Iterators
Input Iterators
The input iterator is one of C++'s five primary iterators and is the simplest and infrequently used. It performs input operations using this iterator successively. Alternatively, it is utilized to read values from the container. It only moves in one direction. Only after reading a value can you increase the iterator. The input iterator cannot, under any circumstances, be decreased.
Features: The C++ input iterator has the following features:
Feature | Description |
---|---|
Equality and Inequality operator | If both iterators point in the same location, they are considered equal. If not, they are characterized as being unequal. |
Usability | Iteration of input occurs exclusively in one direction. These iterators apply to the "single-pass algorithm." |
Dereferencing | Accessing data at a pointer's address requires dereferencing. An asterisk (*) is appended to the variable name while a pointer variable is dereferencing. |
Incrementable | Input iterators can be increased in the forward direction because they are one-way iterators. These iterators have two different incrementing options: pre-increment and post-increment. |
Swappable | It is simple to swap or exchange the values of the two input iterators pointing in opposite places. |
Limitations: The input iterators in C++ have some significant drawbacks, some of which are listed below:
- Input iterators are read-only.
- These iterators are unidirectional, as was already mentioned.
- In a multi-pass algorithm, you cannot use these iterators when you have to move in both directions inside a container.
- You cannot use any other relational operator besides the equality and inequality operators on these iterators.
- Arithmetic operators cannot be used on the input iterators like relational operators.
Output Iterators
The function of output iterators is the exact opposite of input iterators. The output operations performed by this iterator are sequential. In other words, it is used in the value assignment process. It cannot, however, access the values. It is complementary when compared to input iterators, where you may access the values but not assign them. It is a one-way iterator, just like the input iterator. After a value has been assigned, the output iterator can only be increased; it cannot be decreased in any way.
Features: The C++ output iterator has the following features:
Feature | Description |
---|---|
Equality and Inequality operator | If both iterators point in the same location, they are considered equal. If not, they are considered as being unequal. |
Usability | Output iterators can also be used with single-pass algorithms, in which an element can only be accessed a maximum of once. |
Dereferencing | To determine the location for storing the value, dereference an output iterator as a value. |
Incrementable | Output iterators can be increased in the forward direction because they are one-way iterators. These iterators have two different incrementing options: pre-increment and post-increment. |
Swappable | It is simple to swap or exchange the values of the two output iterators pointing in opposite places. |
Limitations: The output iterators in C++ have some significant drawbacks, some of which are listed below:
- These iterators are unidirectional.
- In a multi-pass algorithm, you cannot use these iterators when you have to move in both directions inside a container.
- Similar to input iterators, you cannot use any other relational operators besides equality and inequality operators on output iterators.
- Arithmetic operators cannot be used on the output iterators like relational operators.
Forward Iterators
The input and output iterators' objectives are both served by forwarding iterators. For this reason, these iterators are referred to as the combination of input and output operators. You may both assign and access the values (output iterators' functionality). These iterators are one-way iterators, as their name suggests. You can only move forward when traversing. Additionally, the iterators Bidirectional and Random Access are regarded as legitimate forward iterators.
Features: The C++ forward iterator has the following features:
Feature | Description |
---|---|
Equality and Inequality operator | If both iterators point in the same location, they are considered equal. If not, they are considered as being unequal. |
Usability | Every STL container class uses the forward iterator category. It is the only iterator out of the five types that can do the most basic type of iteration by using a container. |
Dereferencing | Forward iterators are the combination of both iterators. You can apply both rvalue and lvalue. |
Incrementable | Unidirectional forward iterators that can only be increased in the forward direction. These iterators have two different incrementing options: pre-increment and post-increment. |
Swappable | It is simple to swap or exchange the values of the two forward iterators pointing in opposite places. |
Limitations: The forward iterators in C++ have some significant drawbacks, some of which are listed below:
- The forward iterators do not support the offset dereference operator ([]).
- These iterators are unidirectional, as was already mentioned.
- Equality and inequality are the only relational operators that can be used on the forward iterators.
- Arithmetic operators cannot be used on the forward iterators like relational operators.
Bidirectional Iterators
Both directions are possible for bidirectional iterators. Because they give the same functionality as forward iterators, except that they can operate in both directions, they are referred to as forward iterators with two decrement operators. Containers like list, set, and multimap support iterators that move in both directions. Additionally recognized as legitimate bidirectional iterators are the random access iterators.
Features: The C++ bidirectional iterator has the following features:
Feature | Description |
---|---|
Equality and Inequality operator | If both iterators point in the same direction, they are considered equal. If not, they are considered as being unequal. |
Usability | Multi-pass algorithms can also use bidirectional operators. |
Dereferencing | Bidirectional iterators can be applied for both rvalue and lvalue. |
Incrementable/Decrementable | You can increase and decrease the iterator pointer. They are called "bidirectional" for this reason. |
Swappable | It is simple to swap or exchange the values of the two bidirectional iterators pointing in opposite places. |
Limitations: The bidirectional iterators in C++ have some significant drawbacks, some of which are listed below:
- The bidirectional iterators do not support the offset dereference operator ([]).
- You cannot use any other relational operators on the bidirectional iterators except the equality and inequality operators in Bidirectional Iterators.
- Arithmetic operators cannot be used on bidirectional iterators like relational operators.
Random Access Iterators
Of the five iterators, Random Access iterators are regarded as the most accomplished. Bidirectional iterators with random access are another name for these iterators.
Features: Following are some features of the C++ random access iterator:
Feature | Description |
---|---|
Equality and Inequality operator | If both iterators point in the same direction, They are considered equals. If not, they are considered as being unequal. |
Usability | In multi-pass algorithms, random access iterators can be used. |
Dereferencing | Dereferenced Random access iterators can be applied for both rvalue and lvalue. |
Incremental/Decremental | Because they are multi-directional, random access iterators can be used in incrementing and decrementing fashion. |
Swappable | It is simple to swap or exchange the values of the two random-access iterators pointing in opposite places. |
Offset dereference operator | The random access iterators support the offset dereference operator ([]). A random-access iterator can be dereferenced using the offset operator. |
Operations of Iterators
Below are some operations on iterators with syntax.
Iterators | Description | Syntax |
---|---|---|
begin() | The begin() function outputs a pointer pointing to the container's initial element. This pointer is bidirectional since it can point in any direction of the container. | begin() |
end() | A pointer pointing to the element that follows the container's last element represents what the end() method returns. This virtual element holds the address of the previous element; it is not fully present. | end() |
advance() | The iterator is advanced from its current point using the advance() method. As an argument, it accepts an integer. The pointer is advanced to that integer position through the advance() method. | advance(iterator i ,int distance) |
next() | Following an increment of the iterator pointer from the current element, the next() method returns an iterator that points to the following element. | next(iterator i ,int n) |
prev() | The next() method's exact opposite is the prev() method. When you decrease the iterator from the current element, it returns a pointer to the next element. | prev(iterator i, int n) |
inserter() | An exclusive class of iterator methods is the inserter() method. It is used to insert components into a container at a certain location. If an element already exists at the specified location, the new elements may also overwrite existing ones in the container. | inserter (Container & x, Iterator it) |
Providers of Iterators
Iterators and their provider containers are shown in the following table.
ITERATOR | PROVIDER |
---|---|
Input Iterator | istream |
Output Iterator | ostream |
Forward iterator | - |
Bidirectional iterator | List, set, map, multimap, multiset |
Random access iterator | Vector, array, deque |
Difference between Iterators and Pointer
Although pointers and iterators are similar, there are several important differences between them that you need to be aware of.
Pointers: A pointer is a variable that stores the memory address of the variable it is pointing to. A pointer has the same data type as the variable whose memory it holds, just like a standard variable. By simply passing the object's memory address to the functions, the pointer provides them with extensive information.
Syntax:
Iterators: The memory addresses of the STL containers are referenced using iterators. In addition, iterating through the data structures is also accomplished using an iterator. It has access to and commands over values that a pointer cannot.
Syntax:
Difference between Random Access Iterators and Other Iterators
In addition to having significant advantages over other iterators, a Random Access iterator also deals with some drawbacks. Below is a discussion of the main distinctions between the random access iterator and the other iterators:
Random Access Iterators | Other Iterators |
---|---|
Values can be assigned using Random Access iterators. | Input: Only input iterators are accessible. They cannot be used to assign values; they can only read the location data to which the pointer points. |
The values are not accessible through output iterators. Only the values can be assigned using these iterators. | Output: You can determine the container's values using this iterator. |
These iterators can move both ways. These iterators allow you to go both forward and backward. | Forward: Forward iterators are unidirectional. They can only be increased, meaning they can only move forward. They cannot be decreased. |
These iterators support dereferencing the variables using the offset dereferences operator. | Bidirectional: The bidirectional iterators do not support the offset dereference operator ([]). A bidirectional iterator cannot be dereferenced using the offset operator. |
Related articles
There are also C++ articles that are related to this topic. Look it up as well.
Conclusion
- The memory address of the STL container classes is addressed through an iterator.
- Some importatnt operations on iterators such as: begin(), end(), next(), prev() and more.
- A pointer is a variable that stores the memory address of the variable it is pointing to, While The memory addresses of the STL containers are referenced using iterators.
- We can differentiate iterators into five categories which are - input, output, forward, bidirectional, and random access iterators.
- An iterator's primary benefit is that it offers a common interface for all types of containers.
- Iterators provide a general technique for navigating through a container's elements.
- Iterators work through providers, which are list, map, vector, map, multimap, multiset, and more.
- The algorithm becomes independent of the type of container being used because of iterators.
- Iterating through the container is the process of traversing from one element to another using iterators.