What's the best way to iterate over two or more containers simultaneously

memecs picture memecs · Sep 23, 2012 · Viewed 88.7k times · Source

C++11 provides multiple ways to iterate over containers. For example:

Range-based loop

for(auto c : container) fun(c)

std::for_each

for_each(container.begin(),container.end(),fun)

However what is the recommended way to iterate over two (or more) containers of the same size to accomplish something like:

for(unsigned i = 0; i < containerA.size(); ++i) {
  containerA[i] = containerB[i];
}

Answer

Konrad Rudolph picture Konrad Rudolph · Sep 25, 2013

Rather late to the party. But: I would iterate over indices. But not with the classical for loop but instead with a range-based for loop over the indices:

for(unsigned i : indices(containerA)) {
    containerA[i] = containerB[i];
}

indices is a simple wrapper function which returns a (lazily evaluated) range for the indices. Since the implementation – though simple – is a bit too long to post it here, you can find an implementation on GitHub.

This code is as efficient as using a manual, classical for loop.

If this pattern occurs often in your data, consider using another pattern which zips two sequences and produces a range of tuples, corresponding to the paired elements:

for (auto& [a, b] : zip(containerA, containerB)) {
    a = b;
}

The implementation of zip is left as an exercise for the reader, but it follows easily from the implementation of indices.

(Before C++17 you’d have to write the following instead:)

for (auto items&& : zip(containerA, containerB))
    get<0>(items) = get<1>(items);