Reputation: 365
I want to achieve more less the equivalent to this Python code in C++ (but more memory efficient):
a = [1, 5, 3]
additional = 6
for elem in [additional] + a:
print(elem) # prints: 6 1 5 3
# alternative without creating the additional vector:
import itertools
for elem in itertools.chain([additional], a):
print(elem)
The only way that I know to do this in C++ is:
#include <iostream>
#include <vector>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
for (int i = 0; i < a.size() + 1; ++i) {
int cur_elem;
if (i == 0) {
cur_elem = additional;
} else {
cur_elem = a[i-1];
}
std::cout << cur_elem << std::endl;
}
}
Is there a way to do this with a range based for loop? I found the Boost join operator but it seems to use only iterables, so I need to create an extra vector (like in the Python example).
Ideally, the iteration would be without creating the joined object in the memory and with algorithms of the standard library.
Upvotes: 1
Views: 551
Reputation: 5729
It can be done using the upcoming ranges feature.
Here's an example using Eric Niebler's range-v3
library:
#include <iostream>
#include <vector>
#include <range/v3/view/concat.hpp>
#include <range/v3/view/single.hpp>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
for (auto i : ranges::concat_view(ranges::single_view{additional}, a)) {
std::cout << i;
}
}
by using views, all iterator operations are lazy, and no extra memory is used (e.g.: no extra vectors/arrays are created)
Or, without the for
loop:
ranges::copy(ranges::concat_view(ranges::single_view{additional}, a), ranges::make_ostream_joiner(std::cout, ","));
(Honestly, I like the for
version better, though)
There's a small issue with the solution above: concat_view
did not make it into C++20. If you want a strictly compliant solution, you may want to create your own version, or use join_view
instead:
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<int> a = {1, 5, 3};
int additional = 6;
std::vector v{{additional}, a};
for(int i : std::ranges::join_view{v}) {
std::cout << i;
}
}
Upvotes: 6