Iterators in C++ STL (original) (raw)

An iterator is an object that behaves like a pointer to traverse and access elements of a container.

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40};

// Using iterator to traverse the vector
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    cout << *it << " "; 

return 0;

}

`

Container Iterator Functions

List of all methods that returns the iterator to the containers:

#include #include using namespace std;

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

// Normal iterator
cout << "Forward iteration: ";
for (auto it = vec.begin(); it != vec.end(); ++it)
{
    cout << *it << " ";
}
cout << endl;

// Constant iterator
cout << "Forward (read-only) iteration: ";
for (auto it = vec.cbegin(); it != vec.cend(); ++it)
{
    cout << *it << " ";
}
cout << endl;

// Reverse iterator
cout << "Reverse iteration: ";
for (auto it = vec.rbegin(); it != vec.rend(); ++it)
{
    cout << *it << " ";
}
cout << endl;

return 0;

}

`

Output

Forward iteration: 10 20 30 40 50 Forward (read-only) iteration: 10 20 30 40 50 Reverse iteration: 50 40 30 20 10

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

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40};

// Iterator pointing to the first element
auto it = v.begin();

// Dereferencing iterator to access value
cout << "First element: " << *it << endl;

// Dereferencing iterator to update value
*it = 100;

// Printing updated first element
cout << "Updated first element: " << *it << endl;

return 0;

}

`

Output

First element: 10 Updated first element: 100

Incrementing/Decrementing Iterators

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50};

// Iterator pointing to the beginning
auto it = v.begin();

// Incrementing iterator to move to the next element
++it;
cout << "After increment: " << *it << endl;

// Decrementing iterator to move back to the previous element
--it;
cout << "After decrement: " << *it << endl;

return 0;

}

`

Output

After increment: 20 After decrement: 10

Adding/Subtracting Integer to Iterators

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50};

// Iterator pointing to the beginning
auto it = v.begin();

// Moving iterator forward by 2 positions
it = it + 2;
cout << "Element after moving forward by 2: " << *it << endl;

// Moving iterator backward by 1 position
it = it - 1;
cout << "Element after moving backward by 1: " << *it << endl;

return 0;

}

`

Output

Element after moving forward by 2: 30 Element after moving backward by 1: 20

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.

C++ `

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40, 50};

// Defining two iterators
auto it1 = v.begin();
auto it2 = v.begin() + 3;

// Finding the distance between iterators
cout << "Distance between it1 and it2: " << it2 - it1 << endl;

return 0;

}

`

Output

Distance between it1 and it2: 3

Comparing Iterators

#include #include using namespace std;

int main() { vector v = {10, 20, 30, 40};

// Defining two iterators
auto it1 = v.begin();
auto it2 = v.begin() + 2;

// Comparing iterators
if (it1 != it2)
{
    cout << "Iterators point to different elements." << endl;
}

if (it1 < it2)
{
    cout << "it1 comes before it2 in the vector." << endl;
}

return 0;

}

`

Output

Iterators point to different elements. it1 comes before it2 in the vector.

Types of Iterators in C++

STL iterators can be divided on the basis of the operations that can be performed on them.

1. Input Iterator

2. Output Iterator

3. Forward Iterator

4. Bidirectional Iterator

5. Random Access Iterator

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++:**back_insert_iterator: Inserts at the back of the container.**front_insert_iterator: Inserts at the front of the container.**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:

**Function **Description **Syntax
std::advance Advances an iterator by a specific number of positions. **advance(_it, n)
std::next Returns the iterator that is a specified number of positions ahead of the given iterator. **next(_it, n)
std::prev Returns the iterator that is a specified number of positions behind the given iterator. **prev(_it, n)
std::distance Returns the number of elements between two iterators. **distance(_it1, it2)
std::begin Returns an iterator to the first element of the given container. **begin(_container)
std::end Returns an iterator to the element following the last element of the given container. **end(_container)
std::rbegin Returns a reverse iterator to the last element of the given container. **rbegin(_container)
std::rend Returns a reverse iterator to the element preceding the first element of the given container. **rend(_container)
std::inserter Creates an insert iterator that inserts elements into a container at a specified position. **inserter(_container, position)
std::back_inserter Creates a back insert iterator that appends elements to the end of a container. **back_inserter(_container)
std::front_inserter Creates 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.

C++ `

#include #include using namespace std;

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

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

// Iterating through the set
while (it != s.end())
{

    // Accessing value via iterator
    cout << *it << " ";

    // Moving to the next element
    ++it;
}

return 0;

}

`

**Explanation: As shown in the code above, we traverse the set container. Similarly, we can use the same approach to traverse any container.

Reversing a Container

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

C++ `

#include #include using namespace std;

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

// Defining a reverse iterator pointing to the last element
auto it = vec.rbegin();

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

return 0;

}

`

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.

C++ `

#include #include #include #include using namespace std;

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

// Count the number of occurrences of 10 in vector and multiset
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

**Note: Most iterator operations like ++, --, *, and comparison take O(1) time, while operations like distance() and advance() take O(n) for non-random iterators and O(1) for random access iterators.