que iteradores iterador español ejemplos definicion c++ stl iterator

c++ - iteradores - que es un iterador en java



Descartar la salida de una función que necesita un iterador de salida (4)

¿Tienes Boost disponible? Si es así, podría usar un function_output_iterator envolviendo una función vacía.

Aunque no es ideal. Cualquiera que sea el iterador que use, necesitará crear una instancia de value_type para return in operator *, incluso si lo descarta.

Supongamos que hay una función de plantilla en C ++ que hace un trabajo útil pero también genera una secuencia de valores a través de un iterador de salida. Ahora supongamos que esa secuencia de valores a veces es interesante, pero en otros no es útil. ¿Hay una clase de iterador lista para usar en el STL que pueda ser instanciada y pasada a la función e ignorará los valores que la función intente asignar al iterador de salida? Para decirlo de otra manera, envíe todos los datos a / dev / null?


No es difícil escribir uno.

template<typename T> class NullOutputIterator { public: NullOutputIterator() {} NullOutputIterator& operator++() { return *this; } NullOutputIterator& operator++(int) { return *this; } T& operator*() { return m; } T* operator->() { return &m; } private: T m; };

No lo he probado, y probablemente falte algo importante, pero creo que esta es la idea.


El STL no proporciona dicho iterador. Pero podría codificarlo usted mismo (probó ese código):

struct null_output_iterator : std::iterator< std::output_iterator_tag, null_output_iterator > { /* no-op assignment */ template<typename T> void operator=(T const&) { } null_output_iterator & operator++() { return *this; } null_output_iterator operator++(int) { return *this; } null_output_iterator & operator*() { return *this; } };

No necesita ningún dato al usarlo como resultado del operator* . El resultado de *it = x; no se usa en los requisitos del iterador de salida, por lo que podemos darle un tipo de void de retorno.

Editar: veamos cómo funciona este operator* . El estándar dice en 24.1.2 / 1 sobre los requisitos de un iterador de salida que en ambos casos:

*it = t; *it++ = t;

Que el resultado de esas expresiones no se usa. Eso es lo que hace que esto funcione:

null_output_iterator it; *it; // returns a null_output_iterator& per definition of the `operator*`. *it = some_value; // returns void per definition of the templated `operator=`.

Ahora no necesitamos tener ningún dato que devolvamos en el operator* : simplemente usamos el iterador mismo. Tenga en cuenta que el operador con plantilla = no sobrescribe el operador de asignación de copia integrado. Todavía se proporciona.


Basé el mío en std :: back_insert_iterator , pero sin el contenedor:

#include <iterator> template<typename T> class NullOutputIter : public std::iterator<std::output_iterator_tag,void,void,void,void> { public: NullOutputIter &operator=(const T &) { return *this; } NullOutputIter &operator*() { return *this; } NullOutputIter &operator++() { return *this; } NullOutputIter operator++(int) { return *this; } };

Esto es similar a la respuesta de Johannes, pero sin la plantilla operator= que toma lo que sea. Me gusta escribir fuerte Quiero que *it = wrong_type_thing sea ​​un error en tiempo de compilación. También esto usa void para los diversos parámetros de la plantilla para std::iterator , como los iteradores de salida en la biblioteca estándar.

Esto también es similar a la solución de Mark, pero (a) hereda correctamente de std::iterator y (b) no tiene la variable de estado interno innecesaria.