I have two std::vector
s 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;
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++.
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:
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.
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.
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_wrapper
s. 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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With