Функция возвращает базовый класс вместо производного, это ошибка кодирования или ошибка Visual C ++?

Учитывая следующий код, GCC обрабатывает нормально. Visual C ++ 2010-2015, однако, выдает следующее сообщение об ошибке, указывающее, что он рассматривает член итератора reverse_iterator как его базовый тип, а не его производный тип:

«Ошибка 1, ошибка C2039:« get »: не является членом« std :: iterator »<std :: random_access_iterator_tag, element_type, ptrdiff_t, element_type *, element_type &>«»

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

#include <iostream>
#include <iterator>template <class element_type> class container
{
public:
class iterator : public std::iterator<std::random_access_iterator_tag, element_type, std::ptrdiff_t, element_type *, element_type &>
{
private:
element_type *a;

public:
element_type * get()
{
return a;
}

void set(element_type *value)
{
a = value;
}
};class reverse_iterator : public std::reverse_iterator<iterator>
{
private:
iterator der1;

public:
iterator base()
{
return iterator(der1);
}
};

};int main()
{
using namespace std;

container<int>::iterator c;
container<int>::reverse_iterator d;

cout << c.get() << " ";
cout << d.base().get() << endl;
return 0;
}

Очевидно, что если вы скомпилируете это, вы обнаружите, что функции c.get () отлично работают, d.base (). Get () выдает сообщение об ошибке.

Это построенный пример специально для иллюстрации проблемы. Пожалуйста, не предоставляйте ответы, не относящиеся к данной проблеме.

Обратите внимание, что эта ошибка не возникает, когда используется другой искусственно созданный базовый класс — он специфичен для std :: iterator в visual studio.

ПРИМЕЧАНИЕ: Спасибо 1201ProgramAlarm за ответ на вопрос. Решение состоит в том, чтобы прояснить пространство имен экземпляра итератора в reverse_iterator, чтобы использовался контейнер :: iterator. Для этого вы просто используете «typename container :: iterator» вместо «iterator» в объявлении reverse_iterator.

1

Решение

reverse_iterator происходит от std::iterator (Оно в <xutility>) так ваши ссылки на iterator в вашем reverse_iterator класс будет ссылаться на версию std, а не на версию вашего класса.

3

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

Не наследуй от std::reverse_iterator,

#include <iterator>template <class element_type> class container
{
public:
class iterator : public std::iterator<std::random_access_iterator_tag, element_type, std::ptrdiff_t, element_type *, element_type &>
{
private:
element_type *a;

public:
element_type get()
{
return *a;
}

void set(element_type *value)
{
*a = value;
}
};

using reverse_iterator = std::reverse_iterator<iterator>;

iterator begin();

reverse_iterator rbegin() {
return std::make_reverse_iterator( end() );
}
};
0

По вопросам рекламы [email protected]