Dereference an Iterator in C++

Zeeshan Afridi Oct 12, 2023
  1. What is an Iterator in C++
  2. Dereference in C++
  3. Why We Can’t Dereference an Iterator in C++
Dereference an Iterator in C++

Iterators are another powerful mechanism in C++ that helps you iterate over complex data structures like a tree and sets where we don’t have the indices of elements inside, like an array.

What is an Iterator in C++

In C++, an iterator is an object like a pointer, pointing to the elements inside an array, list and any other data structure. We use an iterator to iterate the container elements; although we can use the conventional loops, iterators have the upper hand on iterating through a container.

It provides a very generic approach to traversing through the elements of a container.

In general data structures like arrays, we can use the index variable to loop through the container, but in advanced data structures like a tree or unordered data structures where we don’t have the index variable to loop through, we use iterators to traverse it.

The container provides the data type to the iterators, and the container class provides two basic functions which help the iterator in iterating through the elements of the container.

  1. Begin() - it returns the first element of the container.
  2. End() - it returns the next to the last element of the container.

Let’s understand through a proper code example.

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

int main() {
  // Declaring a vector
  vector<int> numbers = {1, 2, 3, 4, 5};

  // Declaring an iterator
  vector<int>::iterator i;

  int j;
  cout << "Traversing using loop = ";

  // Accessing the elements using loops
  for (j = 0; j < 5; ++j) {
    cout << numbers[j] << ", ";
  }

  cout << endl << "Traversing using Iterators = ";

  // Accessing the elements using iterators
  for (i = numbers.begin(); i != numbers.end(); ++i) {
    cout << *i << ", ";
  }

  // Adding another element to the vector
  numbers.push_back(6);

  cout << endl << "Traversing using loops after adding new value to numbers = ";

  // After adding a new value to the numbers vector
  for (j = 0; j < 5; ++j) {
    cout << numbers[j] << ", ";
  }

  cout << endl
       << "Traversing using iterators after adding new value to numbers = ";

  // Accessing the elements using iterators
  for (i = numbers.begin(); i != numbers.end(); ++i) {
    cout << *i << ", ";
  }
  return 0;
}

Output:

Traversing using loop = 1, 2, 3, 4, 5,
Traversing using Iterators = 1, 2, 3, 4, 5,
Traversing using loops after adding new value to numbers = 1, 2, 3, 4, 5,
Traversing using iterators after adding new value to numbers = 1, 2, 3, 4, 5, 6,

This program demonstrates the difference between the usage traversing through a container using loops and iterators. In the above code, the iterator is keeping track of the code and dynamically adopts if any changes are made in the code.

While in loops, you need to statically update the code for loops. The iterator is achieving the code reusability factor.

In the iterator, the begin() function gets the first element of the container, and the end() gets the next to the last element.

Dereference in C++

The dereference operator in C++ is used to access or manipulate data in a memory location pointed to by a pointer. The * asterisk symbol is used with the pointer variable when differencing the pointer variable, and it refers to a pointed variable, which is called dereferencing of pointers.

Code Example:

#include <iostream>
using namespace std;

int main() {
  int a = 9, b;
  int *p;  // Un-initialized Pointer
  p = &a;  // Store the address of a in pointer p
  b = *p;  // Put the Value  of the pointer p in b
  cout << "The value of a        =   " << a << endl;
  cout << "The value of pointer p =   " << *p << endl;
  cout << "The value of b        =   " << b << endl;
}

Output:

The value of a        =   9
The value of pointer p =   9
The value of b        =   9

We initially assign 9 to a and then define a pointer p. Next, we assign the address of a to p, which is a pointer, and at the end, we assign the pointer to a variable b of integer data type.

Now upon displaying, the a, p, and b are getting the same output as 9 because p has the address of a, which helps us use anywhere to display the value of a.

Why We Can’t Dereference an Iterator in C++

In C++, you cannot dereference an iterator straight away because the end() function returns an iterator and object as a pointer, which isn’t a valid member of the data structure.

When you dereference at the end, it throws an error because the purpose of the end pointer is only to see when you have reached it.

Begin() returns the location when the container isn’t empty, in other words, to satisfy this condition.

v.begin() != v.end()  // this condition checks, if the container is empty or not

But if you need access to the last element, you can use the code below.

vector<object>::const_iterator i = vectorOfObjects.end();
i--;
cout << *i << endl;  // this prints the last element of the container

As a reminder, this code only works when your vector contains at least one element.

Code Example:

#include <iostream>
#include <string>
#include <vector>

using namespace std;
struct Student {
  int roll;
  string name;
  int age;
};

int main() {
  Student s1, s2, s3;  // Objects of strucu
  vector<Student> ListOfStudents;

  s1.roll = 1;  // populating the data members of Student
  s2.roll = 2;
  s3.roll = 3;

  s1.name = "Mike";
  s2.name = "John";
  s3.name = "Tom";

  s1.age = 15;
  s2.age = 16;
  s3.age = 14;

  ListOfStudents.push_back(s1);
  ListOfStudents.push_back(s2);
  ListOfStudents.push_back(s3);

  vector<Student>::const_iterator iter =
      ListOfStudents.begin();  // begining position

  while (iter != ListOfStudents.end()) {  // if the container is empty or not
    cout << "Roll number " << iter->roll << " is " << (*iter).name
         << " and he is " << iter->age << " years old." << endl;
    ++iter;
  }
  return 0;
}

Output:

Roll number 1 is Mike and he is 15 years old.
Roll number 2 is John and he is 16 years old.
Roll number 3 is Tom and he is 14 years old.
Zeeshan Afridi avatar Zeeshan Afridi avatar

Zeeshan is a detail oriented software engineer that helps companies and individuals make their lives and easier with software solutions.

LinkedIn

Related Article - C++ Iterator