Реализация оператора- & gt; в классе итератора адаптера диапазона

Давайте рассмотрим очень базовый класс адаптера диапазона, который охватывает диапазон и выполняет итерации по всем другим элементам исходного диапазона, если вы выполняете итерацию по адаптеру.

for (const auto & e : everyOtherElement(originalRange))

При написании такого класса адаптера диапазона необходимо написать соответствующий класс итератора для этого адаптера, чтобы сделать его итеративным и вести себя так, как нужно.

Такой класс итератора должен реализовывать все, что требуется для «концепции», которую вы хотите поддерживать, например InputIterator. Среди прочего, мы должны реализовать operator* вернуть ссылку на представленный элемент, а также operator-> такой, что it->member доступ к членам этого элемента.

Я подумал, что было бы хорошей идеей просто «переслать» эти операторы в реализацию базового итератора, который оборачивает адаптер (давайте на минутку забудем о постоянстве):

struct everyOtherElement {
OriginalIterator b, e; // The begin and end we wrap around
// ...
struct iterator {
OriginalIterator it;
auto operator*() { return *it; }                  // <------
auto operator->() { return it.operator->(); }     // <------
// ...
};
};

Тем не менее operator-> не скомпилируется, если OriginalIterator имеет тип указателя, как для большинства std::vector реализации и, конечно, сырые массивы. Поскольку такие итераторы не являются типами классов, запись не допускается. it.operator->(),

Как я должен реализовать operator-> сделать итератор максимально прозрачным? Должен ли я реализовать operator-> с точки зрения operator*то есть просто писать (*it).m вместо it->m, Я полагаю, что это не удастся, если какой-то итератор реализует их, чтобы означать разные вещи … (Хотя это было бы плохо, не так ли? Или это запрещено InputIterator концепция?)

Это хорошая идея, чтобы реализовать его как просто возвращая оригинальный итератор, так как operator-> рекурсивно применяется автоматически до тех пор, пока возвращается не указатель?

        auto operator->() { return it; }

1

Решение

Смотрите, например, стандартную спецификацию адаптеров итераторов. move_iterator:

pointer     Iterator

они определяют pointer введите как Iterator и действительно верни это оператором ->

1

Другие решения

Других решений пока нет …