Nunca he implementado STL-como iteradores y trato de entender cómo implementar una cosa muy básica basada en punteros. Una vez que se tiene esta clase voy a ser capaz de modificarlo para hacer cosas más complicadas. En consecuencia, este es un primer paso, y la necesito para ser roca sólida para entender cómo escribir mi propia iteradores (sin impulso).
He escrito el siguiente código y sé que hay errores en ella. Me pueden ayudar a diseñar correctamente un Iterador de Acceso Aleatorio clase inspirado a partir de que :
template<Type> class Container<Type>::Iterator : public std::iterator<random_access_iterator_tag, Type>
{
//Lifecycle:
public:
Iterator() : _ptr(nullptr) {;}
Iterator(Type* rhs) : _ptr(rhs) {;}
Iterator(const Iterator &rhs) : _ptr(rhs._ptr) {;}
//Operators : misc
public:
inline Iterator& operator=(Type* rhs) {_ptr = rhs; return *this;}
inline Iterator& operator=(const Iterator &rhs) {_ptr = rhs._ptr; return *this;}
inline Iterator& operator+=(const int& rhs) {_ptr += rhs; return *this;}
inline Iterator& operator-=(const int& rhs) {_ptr -= rhs; return *this;}
inline Type& operator*() {return *_ptr;}
inline Type* operator->() {return _ptr;}
inline Type& operator[](const int& rhs) {return _ptr[rhs];}
//Operators : arithmetic
public:
inline Iterator& operator++() {++_ptr; return *this;}
inline Iterator& operator--() { --_ptr; return *this;}
inline Iterator& operator++(int) {Iterator tmp(*this); ++_ptr; return tmp;}
inline Iterator& operator--(int) {Iterator tmp(*this); --_ptr; return tmp;}
inline Iterator operator+(const Iterator& rhs) {return Iterator(_ptr+rhs.ptr);}
inline Iterator operator-(const Iterator& rhs) {return Iterator(_ptr-rhs.ptr);}
inline Iterator operator+(const int& rhs) {return Iterator(_ptr+rhs);}
inline Iterator operator-(const int& rhs) {return Iterator(_ptr-rhs);}
friend inline Iterator operator+(const int& lhs, const Iterator& rhs) {return Iterator(lhs+_ptr);}
friend inline Iterator operator-(const int& lhs, const Iterator& rhs) {return Iterator(lhs-_ptr);}
//Operators : comparison
public:
inline bool operator==(const Iterator& rhs) {return _ptr == rhs._ptr;}
inline bool operator!=(const Iterator& rhs) {return _ptr != rhs._ptr;}
inline bool operator>(const Iterator& rhs) {return _ptr > rhs._ptr;}
inline bool operator<(const Iterator& rhs) {return _ptr < rhs._ptr;}
inline bool operator>=(const Iterator& rhs) {return _ptr >= rhs._ptr;}
inline bool operator<=(const Iterator& rhs) {return _ptr <= rhs._ptr;}
//Data members
protected:
Type* _ptr;
};
Muchas gracias.
¿Qué errores? Errores del compilador? Enlazador de errores? Errores de tiempo de ejecución? Los errores lógicos? Algo más?
«Sé que hay errores» — esto es algún tipo de prueba? Creo que no es el sitio adecuado para que…
Un puntero es un iterador. ¿Cuál es el propósito de envolver con una clase?
El propósito es entender cómo implementar correctamente una clase iterator (en particular, la función de firmas y lo que la función de hacer).
Así que usted realmente no necesita
«Sé que hay errores» — esto es algún tipo de prueba? Creo que no es el sitio adecuado para que…
Un puntero es un iterador. ¿Cuál es el propósito de envolver con una clase?
El propósito es entender cómo implementar correctamente una clase iterator (en particular, la función de firmas y lo que la función de hacer).
Así que usted realmente no necesita
public
por todo el lugar, pero como usted no tiene los datos de los miembros en ellos no hace ninguna diferencia. return Iterator(_ptr+rhs);
en teoría crea un extra temporales innecesarios, que sólo podría return _ptr+rhs;
.
OriginalEl autor Vincent | 2012-08-23
En general, su enfoque es correcto. El postfix incremento/decremento operador debe devolver por valor de, no por referencia. También tengo dudas acerca de:
Este le dice a todos que esta clase iterator es implementado alrededor de los punteros. Me gustaría tratar de hacer que este método sólo se puede llamar por el contenedor. Mismo para la asignación de un puntero.
La adición de dos iteradores no tiene sentido para mí (me gustaría dejar «iterador+int»). La resta de dos iteradores señala el mismo contenedor podría tener algún sentido.
operator[]
demasiado, pero no para los iteradores de acceso aleatorio! en.cppreference.com/w/cpp/concept/RandomAccessIteratorgracias. Se corrigió.
Creo que usted necesita
inline difference_type operator-(const Iterator&)
en lugar deinline Iterator operator-(const Iterator&)
. No creo que se necesita el mismo paraoperator+
. Algunos de los algoritmos (comostd::sort
) no parecen funcionar sin ladifference_type operator-
. Usted no puede tener ambas, ya que sólo el retorno de tipos diferentes.OriginalEl autor Alexander Chertov
El código tiene los siguientes problemas:
Iterator(Type* rhs)
podría ser privado y laContainer
podría ser marcado comoIterator
amigo’s, pero que no es estrictamente necesario.operator=(Type* rhs)
es una mala idea. Que no se qué tipo de seguridad se acerca.Iterator
, noIterator &
.std::iterator<std::random_access_iterator_tag, Type>::difference_type
en lugar deconst int &
.const
.Recurso útil: RandomAccessIterator @ cppreference.com
Aquí es una versión fija de su código:
Iterator operator++(int) const
– no puede ser constOriginalEl autor cubuspl42
Echar un vistazo a cómo Impulsar hacerlo, los iteradores en impulso/contenedor/vector.ch –
vector_const_iterator
yvector_iterator
son razonablemente fáciles de entender puntero basado en los iteradores.OriginalEl autor Silas Parker