Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easy way to iterate through multiple std::vectors in C++

Tags:

c++

I have two std::vectors of same type, and I need to iterate through both of them using the same routine. Something like this:

std::vector<int> values1, values2;
int counter = 0;
for (int val : values1) counter += val;
for (int val : values2) counter += val;

Is there any simple way to write the last two lines in a single loop, to avoid code repetition? Something that would look like this:

std::vector<int> values1, values2;
int counter = 0;
for (int val : values1, values2) counter += val;
like image 555
Pericles Carvalho Avatar asked Nov 11 '20 22:11

Pericles Carvalho


People also ask

How to iterate over vector in C++?

We will learn different ways to loop over vector elements. The methods which we are going to learn are: By Using for Loop to Iterate Over Vector in C++. By using vector iterators. By Using a Range-based Loop to Iterate Over Vector. By Using the std::for_each Algorithm to Iterate Over Vector. 1. By Using for Loop to Iterate Over Vector in C++.

How to iterate through vector without using iterators in STL?

The iterator is not the only way to iterate through any STL container. There exists a better and efficient way to iterate through vector without using iterators. It can be iterated using the values stored in any container. Below is the syntax for the same for vectors:

How to get the start and end iterator of a vector?

In C++, vector class provides us two functions using which we can get the start and end iterator of the vector. These two functions are begin (), end (). begin () function is used to get the pointer pointing to the start of the vector and end () functions is used to get the pointer pointing to the end of the vector.

Which value is used to traverse vectors in C++?

Explanation: Here itr is the value stored in vector which is used to traverse vectors. Below is the program to illustrate the same: Updating values in vector: For updating values in a vector without using iterators traverse the values stored in vector using reference and updated the value.


2 Answers

If you don't need to access either vector after iterating over them, you could move them into a std::initializer_list and then iterate over that:

std::vector<int> values1{1, 2, 3};
std::vector<int> values2{4, 5, 6};

for (const auto& v : {std::move(values1), std::move(values2)}) {
    for (auto value : v) {
        std::cout << value << ' ';
    }
}

// prints "1 2 3 4 5 6 "

As ShadowRanger pointed out below, moving from the original vectors isn't necessary if we instead iterate over an initializer list of std::reference_wrappers. This can be done by swapping std::move with std::cref (or std::ref if you need to mutate them):

for (const auto& v : {std::cref(values1), std::cref(values2)}) {
    for (auto value : v.get()) {
        std::cout << value << ' ';
    }
}
// prints "1 2 3 4 5 6 ", as before
like image 172
Brian Avatar answered Sep 28 '22 00:09

Brian


No, there isn't, sorry. At least not directly in the language.

Boost can do it:

for (int val : boost::range::join(values1, values2))
   counter += val;

Because Boost can do it, you could make something to do it as well, by making an iterator type of your own that casts a "view" over both collections.

But, particularly in the simple case you've shown, it's often not worth it. If your loop body is more complex, I recommend hiving it off into a function that takes int. This can just be a lambda declared immediately above the loop. That's what I do.

like image 22
Asteroids With Wings Avatar answered Sep 27 '22 23:09

Asteroids With Wings