×

Search anything:

map::begin and map::end in C++

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

In this article, we have covered the concept of map::begin and map::end in C++ STL along with C++ code examples.

Table of contents

Following, is the list of contents that would be discussed in this article

  • Introduction to maps
  • Uses of a map
  • Accessing elements of a map
  • Using the begin() function in a map
  • Using the end() function in a map

Introduction to maps

Maps are special data-structure in c++, that store data in the form of a key value pairs. They are termed as a map since each key in this data-structure is mapped to its corresponding value. Maps use a Binary Search Tree to store these key, value pairs. It uses a pair data-structure to map the keys to their corresponding values.

Uses of a map

Maps can be used for many different purposes, such as storing a property for some particular object of any type, find any object from a huge collection of data, storing ordered data, and, much more.

Example of a map

// Example to demostrate basic use of a map

#include <iostream>
#include <map>

using std::map;
using std::cout;

int main () {
     map<char, int> example;
     
     example['z'] = 11;
     example['x'] = 12;
     example['y'] = 13;
     
     cout << "Printing the contents of a map:\n";
     for (auto iter:example) {
         cout << iter.first << ": " << iter.second << '\n';
     }
     
     return 0;
}

The above code would emit the following output:

Printing the contents of a map:
x: 12
y: 13
z: 11

Note: As we can observe from the above example maps in c++ sort the data stored by the order of the key

Accessing elements of a map

We have looked at inserting elements as key value pairs in a map, but what about accessing an individual element in a map? To achieve this we can use indexing, i.e., provide a key as an index, like so,

cout << element['x'] << '\n';

If their exists a key with the same value as the given index, then the value stored with that key will be returned.

Another method is to use the Iterators, which we will learn in todays topic.

Iterator functions in a map

Iterator functions are functions that return the iterator of any collection type data-structure. These functions allow us to navigate such data-structures easily. They also provide us with an ability to find any specific data in any such data-structure.

An iterator is just a pointer of restricted type pointing to a specific location on a collections data-structure. Iterators only exist for collections, and not individual data-types.

In a map, the iterators point to a specific pair data structure stored on the Binary Search Tree, in the map.

Note: An iterator is only a pointer and how it is located and returned is dependent on the type of data-structure

Maps in c++ provide multiple iterator functions, the ones we will be discussing today are:

  • The map::begin() function,
  • The map::end() function

The map::begin() function

map::begin() as its name suggests, returns an iterator pointing to the beginning of the map. This allows for accessing the first element in a map, and, provide a starting point to traverse the entire map.

Example:

//Includes are not shown in this example

int main () {
    map<int, int> example;
    
    example[75] = 343;
    example[42] = 117;
    example[95] = 12;
    
    cout << "Map begins at key: " << example.begin()->first << '\n';
    cout << "Value stored at beginning of map: "
         << example.begin()->second
         << '\n';

    return 0;
}

The above code will emit the following output:

Map begins at key: 42
Value stored at beginning of map: 117

We can use this function to traverse the entire map using the following method scheme,

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    for (auto iter = example.begin(); iter != example.end(); i++) {
        cout << "Key: " << iter->first << " value: " << iter->second << '\n';
    }
    return 0;
}

The example.begin() returns the iterator pointing to the beginning of the the map, which is then assigned to the variable iter. example.end() returns another iterator to the end of the map, we will learn about it later in the article. Since, iter is an iterator, it can also behave like any other pointer, which means that it can be incremented and decremented like any other pointer. So, we start a for loop where iter is initially set to example.begin and is incremented till it reaches example.end() and for each value of iter we print its value.

Since iter is a pointer pointing to a specific pair in the map, we would have to use the -> operator to refer to the values stored in the pair.

The map::end() function

map::end() returns an iterator to the end of the map. It tells that the map no longer contains any value. It is useful in cases where we need to find an element in a map. If a particular element is not found, then we can safely return the iterator returned by map::end().

Example:

For the earlier mentioned example if we call the end function like so,

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    cout << "Map ends at key: " << example.end()->first << '\n';
    cout << "Value stored at ending of map: "
         << example.end()->second
         << '\n';

    return 0;
}

We receive the following output,

Map ends at key: 3
Value stored at ending of map: 0

As we can notice that neither of the elements from the key value pair at the given iterator location exist in our map. This is because map::end() does not return the iterator pointing to the last element of the map, but to a location outside of the given map.

This is extremely helpful in scenarios where we need to find an element in a given map,

Example:

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    
    // The key exists
    auto key_iterator = example.find(343);
    if (key_iterator != example.end()) {
        cout << "Key found with value: " key_iterator->second << '\n';
    }
    else {
        cout << "Key not found\n";
    }
    
    // The key does not exist
    key_iterator = example.find(900);
    if (key_iterator != example.end()) {
        cout << "Key found with value: " key_iterator->second << '\n';
    }
    else {
        cout << "Key not found\n";
    }
    return 0;
}

This produces the give output:

Key found with value: 343
Key not found: 3

If the map::end() function returned the iterator pointing to the last element stored in the map, then it would have been difficult to check if the element returned by map::find() was not found or was just the last element of the map.

So, how does one find the last element of the map? Luckily for us there exists a way to get the last element of the map using map::end().
Let us see how it works...

int main () {
    // --Map initialization and insertion of values is same as the previous example-- //
    
    // Print all the elements of the map
    for (auto iter:example) {
        cout << "Element with key: " << iter.first 
            << " is: " << iter.second 
            << '\n';
    }
    
    // Print the last element of the map using `map::end()`
    cout << "Last element of the map is: " 
        << (--example.end())->second
        << '\n';
    return 0;
}

The output for the following code is,

Element with key: 42 is: 117
Element with key: 75 is: 343
Element with key: 95 is: 12
Last element of the map is: 12

Let us analyze what we have done here,

  • First we print the entire map to know what should be the last element of the map by basic traversal, this is done to check the validity of our actual logic.
  • Now let us analyze this part of code which prints the last element using map::end(),
    cout << "Last element of the map is: " 
        << (--example.end())->second
        << '\n';
  • We see something funny over here, what is (--example.end())->second?

As we learned earlier iterators are just restricted pointers, that point to a given location in the collection data-structure. That means if I decrement the iterator by 1 I would be able to get the location of element that was stored before the iterator we had in hand. We know that map::end() returns an iterator that is 1 greater than the location of the last element, we move the pointer one step backwards and access the last element stored in the map.

Conclusion

Maps in c++ or any other language for that matter are a brilliant way to store data. They provide with the ability to store data in the form of a key value pair which can be quite helpful when sending data across multiple services, like an API. Instead of accessing the value by some numbered index, we can use sensible keys to be used as index thus making code more readable, and functional. The map::begin() and map::end() functions make using maps even more easier as they allow us for easily navigating and searching in the map. Though they are only two of the many such functions available in a map, they still provide enough basic functionality to get started.

With this article at OpenGenus, you must have the complete idea of map::begin and map::end in C++ STL.

map::begin and map::end in C++
Share this