Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to iterate over two containers without using two for loops

Is there a way to iterate over two containers (one followed by the other), without using two for loops.

My intention is to do something like this

vector<int> a{ 1,2,3 };
vector<int> b{ 4,5,6 };

auto it = a.begin();
auto end = b.end();

for (; it != end; ++it)
{
    if (it == a.end())
    {
        it = b.begin();
    }
    // do something with *it
}

to print

1 2 3 4 5 6

(of course it doesn't work. The explanation is in this answer )

I do not want to write two for loops and duplicate the code inside the loop. Is there a way to iterate over a followed by b with a single for loop?

The only thing I can think of is either copy/move the second container to the first or create a new vector combining a and b, and then iterate over it. I do not want to do this either, because this will mean expensive copy operations.

like image 246
Mathai Avatar asked Dec 08 '22 12:12

Mathai


2 Answers

Using range-v3, your go-to for all things range-related in C++17 or earlier:

for (int i : view::concat(a, b)) {
    std::cout << i << ' ';
}
like image 120
Barry Avatar answered Jun 01 '23 15:06

Barry


one more way to do it using boost range

#include <vector>
#include <iostream>

#include <boost/range.hpp>
#include <boost/range/join.hpp>

int main()
{
  std::vector<int> a{ 1,2,3 };
  std::vector<int> b{ 4,5,6 };

  for(auto& x : boost::join(a, b)) {
      std::cout << x << " ";
  }
  std::cout << std::endl;
}
like image 32
Sandro Avatar answered Jun 01 '23 17:06

Sandro