2009-06-30 9 views
7

Escribí mi propia plantilla de contenedor con un iterador. ¿Cómo implemento const_iterator?C++: ¿Cómo escribir un const_iterator?

template <class T> 
class my_container { 
private: 
    ... 

public: 
    my_container() : ... { } 
    ~my_container() { } 

    class iterator : public std::iterator<std::bidirectional_iterator_tag, T> { 
    public: ... 

Respuesta

4

La única diferencia debe ser que cuando se de-referencia de un iterador const se obtiene una referencia constante en lugar de una referencia al objeto en el contenedor.

+1

¿Qué ocurre con los métodos que toman los iteradores como argumentos o como iteradores de retorno? Tengo que sobrecargarlos para const_iterators? Parece un montón de código repetido. –

+0

iteradores deben ser convertibles en const_iterators, por lo que no tendrá que sobrecargar si solo necesita un const_iterator. Lo hace para funciones como begin(), end(), pero no hay forma de evitarlo, ya que const también es parte de la firma del método. –

+2

@ Posco Grubb: No. Si tiene métodos que toman iteradores, entonces los plantilla. El método debería funcionar para cualquier cosa que actúe como un iterador. Si el método requiere un iterador en lugar de un const_iterator, el compilador generará el error apropiado. –

2

La forma más fácil de implementar iteradores es boost::iterator. Si desea rodar su propia, creo que la firma debe ser:

class const_iterator : public std::iterator<std::bidirectional_iterator_tag, const T> { 

con la implementación de la misma (suponiendo que está utilizando reference_type y así sucesivamente en sus firmas de función)

+0

Me sorprendí al encontrar que iterator_traits :: const_iterator> :: value_type es int, no int const (T, en lugar de const T en su código). Creo que const tiene más sentido sin embargo. Sin embargo, la línea de fondo es que si quiere hacer coincidir los contenedores estándar, necesita usar T. –

+0

no const. Lo importante con un iterador de constantes es que no puede usarlo para cambiar la colección que se está iterando. Entonces, T o const T & son apropiados. No es necesario usar const con solo T (ya que la devolución será una copia) –

+0

Bueno, si quiere especificar que by-value es no const, debe especificar todos los parámetros: class const_iterator: public std :: iterator . Me gustaría ir con brevedad (con alguna protección adicional contra errores de asignación/igualdad) en lugar de la conformidad con el vector STL, pero es una elección difícil desde el punto de vista del diseño. –

0

Roger Pate, value_types son "sencillo". Sospecho que verás la const si miras iterator_traits :: const_iterator> :: reference, que creo que será "const int &".

Cuestiones relacionadas