Итератор произвольного доступа: что мне не хватает? - PullRequest
2 голосов
/ 07 октября 2019

У меня есть простой контейнер на основе массива, и я хочу сделать для него итератор. Моя цель - заставить работать std :: sort, поэтому я использую итератор произвольного доступа.

Класс итератора:

class MyIterator: public std::iterator<std::random_access_iterator_tag, T> {
        friend class ArraySequence;
    private:
        T* pos;
        MyIterator(T* pos);
    public:
        MyIterator(const MyIterator &it);
        ~MyIterator();
    public:
        typename MyIterator::reference operator*() const;
        typename MyIterator::pointer operator->() const;
        typename MyIterator::reference operator[](const typename MyIterator::difference_type& n) const;
        MyIterator operator++(int);
        MyIterator& operator++();
        MyIterator operator--(int);
        MyIterator& operator--();
        MyIterator operator+(const typename MyIterator::difference_type& n) const;
        MyIterator& operator+=(const typename MyIterator::difference_type& n);
        MyIterator operator-(const typename MyIterator::difference_type& n) const;
        MyIterator& operator-=(const typename MyIterator::difference_type& n);
        bool operator!=(const MyIterator& it) const;
        bool operator==(const MyIterator& it) const;
        bool operator<(const MyIterator& it) const;
        bool operator>(const MyIterator& it) const;
        bool operator<=(const MyIterator& it) const;
        bool operator>=(const MyIterator& it) const;
    };

И его методы:

template <typename T>
ArraySequence<T>::MyIterator::MyIterator(T* pos): pos(pos) {}

template <typename T>
ArraySequence<T>::MyIterator::MyIterator(const MyIterator& it): pos(it.pos) {}

template <typename T>
typename ArraySequence<T>::MyIterator::reference ArraySequence<T>::MyIterator::operator*() const {
    return *pos;
}

template <typename T>
typename ArraySequence<T>::MyIterator::pointer ArraySequence<T>::MyIterator::operator->() const {
    return pos;
}

template <typename T>
typename ArraySequence<T>::MyIterator::reference ArraySequence<T>::MyIterator::operator[](const typename MyIterator::difference_type& n) const {
    return *(pos + n);
}

template <typename T>
typename ArraySequence<T>::MyIterator ArraySequence<T>::MyIterator::MyIterator::operator++(int) {
    return MyIterator(pos++);
}

template <typename T>
typename ArraySequence<T>::MyIterator& ArraySequence<T>::MyIterator::MyIterator::operator++() {
    ++pos;
    return *this;
}

template <typename T>
typename ArraySequence<T>::MyIterator ArraySequence<T>::MyIterator::MyIterator::operator--(int) {
    return MyIterator(pos--);
}

template <typename T>
typename ArraySequence<T>::MyIterator& ArraySequence<T>::MyIterator::MyIterator::operator--() {
    --pos;
    return *this;
}

template <typename T>
typename ArraySequence<T>::MyIterator ArraySequence<T>::MyIterator::operator+(const typename MyIterator::difference_type& n) const {
    return MyIterator(pos + n);
}

template <typename T>
typename ArraySequence<T>::MyIterator& ArraySequence<T>::MyIterator::operator+=(const typename MyIterator::difference_type& n) {
    pos += n;
    return *this;
}

template <typename T>
typename ArraySequence<T>::MyIterator& ArraySequence<T>::MyIterator::operator-=(const typename MyIterator::difference_type& n) {
    pos -= n;
    return *this;
}

template <typename T>
typename ArraySequence<T>::MyIterator ArraySequence<T>::MyIterator::operator-(const typename MyIterator::difference_type& n) const {
    return MyIterator(pos - n);
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator!=(const MyIterator& it) const {
    return pos != it.pos;
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator==(const MyIterator& it) const {
    return pos == it.pos;
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator<(const MyIterator& it) const {
    return pos < it.pos;
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator>(const MyIterator& it) const {
    return pos > it.pos;
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator<=(const MyIterator& it) const {
    return pos <= it.pos;
}

template <typename T>
bool ArraySequence<T>::MyIterator::operator>=(const MyIterator& it) const {
    return pos >= it.pos;
}

template <typename T>
ArraySequence<T>::MyIterator::~MyIterator() {}

Когда я пытаюсь запустить std :: sort, я получаю много ошибок компилятора, таких как «Недопустимые операнды в бинарном выражении ('ArraySequence :: MyIterator' и 'ArraySequence :: MyIterator')" on line "diff_type __len = __last - __first;». Что мне здесь не хватает? Что можно улучшить?

1 Ответ

4 голосов
/ 07 октября 2019

Вы забыли, что вам нужно реализовать operator - для самих итераторов. Поддержка итератора произвольного доступа it1 - it2 для получения расстояния между двумя итераторами. У вас есть operator - для difference_type, но не для самого типа итератора. Вам необходимо добавить перегрузку, например:

template <typename T>
typename MyIterator::difference_type ArraySequence<T>::MyIterator::operator-(const typename ArraySequence<T>::MyIterator& n) const
{
    return pos - n.pos;
}
...