Учитывая следующий код, 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.
reverse_iterator
происходит от std::iterator
(Оно в <xutility>
) так ваши ссылки на iterator
в вашем reverse_iterator
класс будет ссылаться на версию std, а не на версию вашего класса.
Не наследуй от 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() );
}
};