Karponter
@Karponter

Полиморфизм и итерация по пользовательских контейнерах. Начнем?

Имеется пользовательский контейнер по принципу linked list. Связанные между собой узлы.
Стоит задача: подключить к нему итератор.
Класс итератора структуры я наследую от двунаправленного итератора по узлам.
Идея моя в том, чтобы переопределить операторы * и -> таким образом, чтобы они возвращали не конкретный итерируемый узел дерева, а данные, которые хранятся в узле. Иными словами - завуалировать использование структуры узлов и полностью скрыть их от внешнего использования.
Ясное дело, попросту переопределить оператор мне не разрешают, в виду конфликта типов.

template class MyIterator : std::iterator <std::bidirectional_iterator_tag, MyQueueNode<T>> {};

MyIterator подтягивает из std::iterator определенные в нем операторы (* и ->), которые возвращают тип MyQueueNode (что логично, ведь для отслеживания связей между узлами нужно итерироватся по самих узлах а не по данных, которые в них хранятся). Мне же нужно написать для MyIterator операторы (* и ->), которые будут возвращать тип T, на что компилятор говорит "прости, бро, конфликт возвращаемых типов".

Если итерироваться напрямую по данных, то как в таком случае реализовать ++ и -- ?
Быть может есть способ обойти наследование операторов, и прописать новые, игнорируя родительские?
Да и вообще идеи интересно послушать по этому поводу.
  • Вопрос задан
  • 198 просмотров
Решения вопроса 1
@MiiNiPaa
1) Унаследовались от std::iterator вы неверно. Второй параметр это тип который должен получится после разыменования. Если оператор * возвращает Т, то ставьте Т параметром.

2)
MyIterator подтягивает из std::iterator определенные в нем операторы (* и ->),
Какие определённые операторы? std::iterator определяет несколько алиасов типов, вот и всё.

Вам нужно:
а) Хранить в итераторе указатель на ноду.
б) Операторы ++ и -- переводят указатель на следующую/предыдущую ноду
в) Операторы * и -> обращаются к данным в текущей ноде.

Как-то так:

template <typename T>
struct Node
{
    T data;
    Node* next;
    Node* prev;
};

template <typename T>
class list_iterator : public std::iterator<std::bidirectional_iterator_tag, T> 
{
    private:
    
    Node<T>* current;
    
    public:
    
    list_iterator& operator++()
    {
        current = current->next;
        return *this;
    }
    
    T& operator*()
    {
        return current->data;   
    }
};
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы