Tag Archives: Iteration

Looping over the keys and values in a map

Say we have this map:

#include <map>
#include <string>

typedef std::map<std::string, unsigned int> map_string_to_uint;
const size_t n = 12;

map_string_to_uint monthdays;
const char *months[] 
        = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
unsigned int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
for (int m = 0; m < n; ++m) {
    monthdays[months[m]] = days[m];
}

And we want to loop over the keys and values.

Method 1: Use an iterator

    for (map_string_to_uint::const_iterator it = monthdays.begin(); it != monthdays.end(); ++it) {
        std::cout << it->first << ": " << it->second << "\n";
    }

Method 2: Use a range-based for loop (C++11)

    for (const auto& pair : monthdays) {
        std::cout << pair.first << ": " << pair.second << "\n";
    }

Method 3: Use Boost.Foreach

#include <boost/foreach.hpp>

BOOST_FOREACH(const map_string_to_uint::value_type& pair, monthdays) {
    std::cout << pair.first << ": " << pair.second << "\n";
}

Reference: Boost.Foreach

Looping over a container in C++

It’s best to use an algorithm when processing a container, or the contents of any pair of iterators, in C++, but it’s good to know how to iterate when you have to.

Here’s the vector we’re going to use:

#include <iostream>
#include <vector>
#include <algorithm>

typedef std::vector<int> intvec;

int main()
{  
    intvec v(10);
    std::iota(v.begin(), v.end(), 0);
    iterate(v);
}

Method 1: Use iterators

This is the most familiar interface.

void iterate(const intvec& v)
{
    for (intvec::const_iterator it = v.begin(); it != v.end(); ++it) {
        // Do something with *it
    }
}

Method 2: Use indices

Note that only random access containers like vector and deque support indexed access.

void iterate(const intvec& v)
{
    for (intvec::size_type i = 0; i < v.size(); ++i) {
        // Do something with v[i]
    }
}

Method 3: Use Boost.Foreach

This was the most elegant method until C++11.

#include <boost/foreach.hpp>

void iterate(const intvec& v)
{
    BOOST_FOREACH(intvec::value_type el, v) {
        // Do something with el
    }
}

Reference: Boost.Foreach

Method 4: Use a range-based for loop

This is now the recommended method.

void iterate(const intvec& v)
{
    for (const auto& el: v) {
        // Do something with el
    }
}

The yield keyword in Python

Iterables
An iterable is an object of a class that has an iter() method to return an iterator.
The for statement calls iter()

Iterators
An iterator is an object that defines a method next().
When there are no elements left, next() raises StopIteration.

Generators
A generator is a function that acts like an iterator by returning elements with yield.