Метод итератора не наследуется от Const_iterator - PullRequest
0 голосов
/ 04 мая 2018

В коде есть два упрощенных итератора вниз Cit и It.

It публично наследуется от Cit, чтобы разрешить преобразование из It в Cit, как в foo2.

Я думал, что It унаследует int operator-(const self_type& other) const от Cit. Но это не тот случай. Почему?

Если я использую using operator-;, то заставит ли It наследовать оба метода operator- от Cit? Это было бы неправильно.

Тест:

#include <vector>

template<typename C>
class Cit {
    typedef Cit<C> self_type;
public:
    Cit(const C& container, const int ix)
            : container_(&container), ix_(ix) {}

    self_type operator-(const int n) const {
        return self_type(*container_, ix_ - n);
    }

    int operator-(const self_type& other) const {
        return ix_ - other.ix_;
    }

    const int& operator*() const { return (*container_)[ix_]; }

protected:
    const C* container_;
    int ix_;
};


template<typename C>
class It : public Cit<C> {
    typedef Cit<C> Base;
    typedef It<C> self_type;
public:
    It(C& container, const int ix)
            : Base::Cit(container, ix) {}

    self_type operator-(const int n) const {
        return self_type(*mutable_a(), ix_ - n);
    }

    int& operator*() const { return (*mutable_a())[ix_]; }

private:
    C* mutable_a() const { return const_cast<C*>(container_); }
    using Base::container_;
    using Base::ix_;
};

template <typename C>
void foo(Cit<C>& it) {}

int main() {
    typedef std::vector<int> V;
    V a = {0, 1, 2, 3, 4, 5};
    It<V> b(a, 2);
    It<V> c(a, 2);
    foo(b); // convert from It to Cit works.
    b - c;  // <----- This doesn't work. Why?
    // Assert that result of (b - 1) is an It instead of a Cit.
    *(b - 1) -= 1;
}

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Если вы определите один operator- в производном классе, он будет скрывать (тень) все operator- от базового класса.

A using ...; введет все с именем ... в производный класс. Однако self_type operator-(const int n) const из базового класса вернет неправильный тип для производного класса.

Так что вам нужно добавить код котельной пластины, чтобы эта работа работала.

0 голосов
/ 04 мая 2018

Ваш It<>::operator-(const int n) скрывает все operator- от базового класса Cit<>.

Вам нужно добавить using Cit<C>::operator-; к It<>, чтобы эти операторы были видны следующим образом:

template<typename C>
class It : public Cit<C> {
    //...
public:
    //....

    using Cit<C>::operator-;

    self_type operator-(const int n) const {
        return self_type(*mutable_a(), ix_ - n);
    }

https://godbolt.org/g/s76SSv

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...