Reputation: 131970
I have some (templated) iterator pair Iterator begin1
and Iterator end1
. I have a function foo, with signature
template <typename ForwardIterator>
void foo(ForwardIterator begin, ForwardIterator end);
which does something on that range. Now, I want to have foo
act not on the actual range elements, but rather on a transformation of these elements by some lambda or some function bar
. I can't use std::transform or otherwise use temorary storage for the transformed values, since that would take up too much space or since I'm not allowed to allocate anything on the heap.
Now, I know I can implement some kind of adapting iterator myself, but I'd rather use something ready-made and not reinvent the wheel.
So, what's a quick and dirty way to get an appropriate adapting iterator pair I can pass for foo
to do what I want? i.e. for me to be able to call
foo(magic(begin), magic(end))
or
auto new_pair = magic(begin, end);
foo(new_pair.first, new_pair.second);
?
Upvotes: 2
Views: 84
Reputation: 4359
Eric Niebler's range-v3 library provides a very nice solution for this, and is planned to be included in a future standard. Here's a simple example:
std::vector<int> vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
using namespace ranges;
auto rng = vi | view::transform([](int x){ return x % 2; });
foo(rng.begin(), rng.end()); // When foo dereferences these iterators, it
// will see: [1, 0, 1, 0, 1, 0, 1, 0, 1, 0].
This is all lazy and efficient, by the way. :)
Upvotes: 2