Предположим, у меня есть итератор C++, который не только обходит структуру данных, но также применяет преобразование к элементам, когда он разыменован.Возможно ли иметь трансформаторный Iterator в C++?
В реальном мире, например, вот итератор, который выходит за пиксели в растровом изображении, превращая растровый конкретный формат пиксель в удобную структуру:
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
}
};
Теперь, если я хотел бы реализовать Некоммерческий -const iterator (т. е. разрешить пользователю изменять пиксели), каков наилучший способ сделать это?
Некоторые идеи я считал:
я мог бы поставить аксессор методы в
Pixel
структуре вместо простых полей и дать ему ссылку на его владельца на домашний телефон. Это, однако, означает, что если пользователь изменил R, G, B и A, я бы четыре раза конвертировал пиксель в формат пикселя растрового изображения и записывал в память 4 раза.Я мог бы вернуть ссылку на пиксель из итератора и предоставить ему метод
Update()
, который необходимо вызвать, если пиксель был изменен. Это будет неинтуитивно понятным, и пользователи риска не смогут позвонитьUpdate
.Я всегда мог вернуть
Pixel
по значению и предоставить специальный оператор присваивания. ли сломать стандартный шаблон итератора - относящий итератора без разыменования должен переместить итератор, а не обновлять элемент он, указывая на
Я думаю, что идиоматический способ заключается в том, что 'operartor *()' возвращает ссылку (возможно, const) на фактический пиксель. Естественно, итератор мог сохранить ссылку на исходный контейнер. – dmg
Да, но * фактический пиксель * имеет различный формат (например, 16 бит на пиксель с 5-6-5 битами для красно-зелено-синего), и я хотел бы скрыть эту деталь от пользователя, таким образом, я 'm возвращает прокси-объект, а не * фактический пиксель *. Конечно, итератор ссылается на исходный контейнер («битмап») - моя проблема заключается в том, чтобы сообщать итератору, когда ему нужно записать изменения в прокси-объекте обратно в исходный контейнер. – Cygon
Посмотрите на [Boost.Iterator] (http://www.boost.org/doc/libs/1_57_0/libs/iterator/doc/index.html) и [Boost.Range] (http://www.boost.org/doc/libs/1_57_0/libs/range/doc/html/index.html). – Angew