Reputation: 723
I'm new to range-v3. I started by write a program that generates a range of integers, modifies it, and prints out the resulting range. I used a modifier from the actions
library, which rendered my code non-iterable.
Could someone help me understand how to convert a ranges::action::action_closure
into an iterable?
Here's the example I started with - a function that generates and prints out a range of numbers. This code works fine and compiles.
void generate_and_print_numbers_using_streams_and_iterators() {
auto v = views::iota(1, 5); // <-- this code works fine with streams and iterators.
// this works
cout << v << endl;
//this works too
for (auto s: v) {
cout << s << ", ";
}
cout << endl;
// and this works too
for (auto it = v.begin(); it != v.end(); ++it) {
cout << *it << ", ";
}
cout << endl;
}
Then I tried introducing the action I mentioned. This code no longer compiles - v
is no longer a view, but an action_closure
which does not define begin()
and end()
functions.
void generate_and_print_numbers_using_streams_and_iterators() {
// I REPLACED THIS:
// auto v = views::iota(1, 5);
// WITH THIS:
auto v = action::push_back(views::iota(1, 5)) | actions::unique; // Wrapped iota in push_back
// .. the remainder of the function is unchanged
I tried searching through the documentation of ranges-v3, as well as googling this conversion. The only thing I found was the following article that shows how to convert a view to a concrete container (a vector).
I will appreciate any help on this topic.
Upvotes: 0
Views: 674
Reputation: 9525
Actions do not return a light-weight ephemeral object that can be lazily iterated over like view operations do. Actions are applied eagerly to actual containers and return actual containers, but still can be composed together.
In the following std::vector<int>()
is an r-value that gets filled via push_back
which returns an r-value that is then passed to the reverse action. All of this processing happens eagerly, akin to normal nested function calls but using the pipeline syntax:
void do_something_with_a_push_back_action() {
std::vector<int> vec = std::vector<int>() |
ranges::actions::push_back(ranges::views::iota(1, 5)) |
ranges::actions::reverse;
for (int val : vec) {
std::cout << val << "\n";
}
}
Upvotes: 1