I want to use a transform_iterator to make a delta transformation on a range. By delta transformation I mean that r0 should stay the same and the subsequent elements, ri, are mapped to (ri - ri - 1).
My problem is that as far as I can tell a transform_iterator needs a const functor, but my functor needs to remember the previous value. How can I solve this? Should I just write my own iterator?
The reason I want it as an iterator is that in the next step I want to make a range adaptor from it.
EDIT: It seems transform_iterator does allow non-const functors and that it was really my range adaptor that complained about the lack of constness. I'll keep the question open since the discussion about how appropriate it is to use transform_iterator anyway seems interesting.
I don't think you can have this work completely correctly with boost::transform_iterator. This is a simple implementation that seems like it might work at first, but doesn't really work well:
#include <boost/iterator/transform_iterator.hpp>
#include <vector>
#include <iostream>
using std::cout;
struct Delta {
Delta() : prev_value(0) { }
int operator()(int value) const
{
int result = value-prev_value;
prev_value = value;
return result;
}
mutable int prev_value;
};
int main(int,char**)
{
typedef std::vector<int> Items;
typedef boost::transform_iterator<Delta,Items::iterator,int> Iter;
Items items;
items.push_back(4);
items.push_back(3);
items.push_back(8);
{ // prints 4 -1 5 -- excellent
Iter i(items.begin(),Delta()), end(items.end(),Delta());
for (;i!=end;++i) {
cout << *i << " ";
}
cout << "\n";
}
{ // prints 4 0 -- crap
Iter i(items.begin(),Delta());
cout << *i << " ";
cout << *i << "\n";
}
return 0;
}
To really make this work, you need to know when the iterator is advanced, so I think you'll need your own iterator.
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