Assume I have a C++ iterator that not only traverses a data structure but also applies a transformation to the elements when it is dereferenced.
As a real-world example, here's an iterator that goes over the pixels in a bitmap, transforming the bitmap-specific pixel format into a convenient structure:
class ConstPixelIterator {
public: struct Pixel {
float Red;
float Green;
float Blue;
float Alpha;
};
public: ConstPixelIterator(const Bitmap &bitmap);
// ...standard iterator functionality...
public: Pixel operator *() {
// Read from memory and convert pixel format-specific bytes into Pixel structure
}
};
Now if I wanted to implement a non-const iterator (i.e. let the user modify pixels), what is the best way to go about this?
Some ideas I considered:
I could put accessor methods in the
Pixel
structure instead of plain fields and give it a reference to its owner to phone home. This would however mean that if the user changed R,G,B and A, I would convert the pixel into the bitmap's pixel format 4 times and write to memory 4 times.I could return a Pixel reference from the iterator and provide it with an
Update()
method that needs to be called if the pixel was changed. This would be non-intuitive and risk users forgetting to callUpdate
.I could always return the
Pixel
by value and provide a special assignment operator. Does break the standard iterator pattern - assigning to an iterator without dereferencing should move the iterator, not update the element it is pointing at