La especificación C++ sobre qué es exactamente un contenedor STL exige que cualquier tipo de contenedor STL tenga varios campos diferentes disponibles. Algunos, como begin()
y end()
, son funciones, mientras que otros, como iterator
, son tipos. Estas restricciones también se aplican a los iteradores. Esto permite que las funciones de la plantilla de C++ tengan una introspección en sus tipos de argumentos para buscar más propiedades. Por ejemplo, todos los tipos de iteradores STL deben definir un campo iterator_category
que contenga un tipo que codifique sus capacidades. De esta manera, los algoritmos STL pueden tener diferentes implementaciones de diferentes funciones basadas en el poder de los iteradores que aceptan. Un ejemplo de clase es la función distance
, que toma dos iteradores y devuelve el número de espacios entre ellos. Si la entrada es muy baja ForwardIterator
o BidirectionalIterator
esto funciona al avanzar los iteradores y contando cuántos pasos se tomaron, lo cual se ejecuta en O (n). Si la entrada es RandomAccessIterator
, los iteradores solo se pueden restar para obtener el resultado en O (1).
Afortunadamente, por lo general no es necesario enumerar explícitamente todos los typedefs. Hay un tipo de utilidad en el encabezado <iterator>
llamado iterator
que está parametrizado en una gran cantidad de argumentos diferentes. Si define un tipo de iterador personalizado, puede heredar de iterator
para importar toda esta información automáticamente. Es esencialmente una forma más rápida de tener todos los typedef
s en su lugar.
En cuanto a los operadores Lo que hay que sobrecargar, en un mínimo que necesita para obtener ++
(prefijo y postfijo), ==
, !=
, *
(de referencia de puntero), y ->
definido. Todos los tipos de iteradores lo soportan. Para iteradores bidireccionales o superiores, también debe tener --
definido (prefijo y postfijo). Por último, para los iteradores de acceso aleatorio, debe apoyar []
, +
, +=
, -
(copia de seguridad de muchos pasos y restar dos iteradores), -=
, <
, >
, <=
y >=
.
Espero que esto ayude!
Gracias! si escribo typedefs en el código, ¿ya no necesito heredar std :: iterator? – Sean
@Sean: correcto. He escrito iteradores que no heredaron de 'std :: iterator' y siempre han funcionado bien (bueno, algunos han tenido errores, pero ser independiente de' std :: iterator' no fue la causa ... .) –