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?Descartando la salida de una función que necesita un iterador de salida
Respuesta
¿Tiene Boost disponible? De ser 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.
No es difícil escribir una.
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 he probado esto, y probablemente falte algo importante, pero creo que esta es la idea.
El STL no proporciona dicho iterador. Pero podría codificar usted mismo (probado que el 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; }
};
que no necesita ningún dato mediante el uso de sí mismo como el resultado de operator*
. El resultado de *it = x;
no se utiliza en los requisitos del iterador de salida, por lo que podemos darle un tipo de devolución de void
.
Editar: Vamos a entrar en funcionamiento de esta operator*
obras. El estándar dice en 24.1.2/1 acerca de los requisitos de un iterador de salida que en estos dos casos:
*it = t;
*it++ = t;
que el resultado de esas expresiones no se utiliza. Eso es lo que hace este trabajo:
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 necesita tener ningún dato que volvamos en operator*
: Nos limitamos a usar el iterador en sí. Tenga en cuenta que el operador con plantilla = no sobrescribe el operador de asignación de copia integrado. Todavía se proporciona.
¿Podría explicar mejor al operador *? –
Se usa en combinación con el operador con plantilla =. Tricky, usaría una clase de ayuda anidada dev_null. Además, dejaría que el operador ++ (int) devuelva * esto inmediatamente. Esta versión es ineficiente. – MSalters
msalters, la semántica operacional indica que se devuelve un nuevo objeto :) –
que la mina basado 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 plantilla a 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 interna innecesaria.
- 1. de iterador de salida
- 2. C++ funtor al adaptador de salida iterador
- 3. Salida anticipada de la función?
- 4. ¿Cómo exportar la salida de la función
- 5. matriz como salida de una función
- 6. iterador de salida de C++ borrado por tipo
- 7. Interpretación de salida de salida
- 8. Salida de la salida estándar a un archivo y viceversa
- 9. Suprimir salida cout con en una función
- 10. la salida de un hilo
- 11. ¿Cómo puedo sangrar la salida de salida?
- 12. Función de salida de entrada rápida
- 13. ggplot - faceta por salida de función
- 14. Muestra la salida de un comando Bash y mantiene la salida en una variable
- 15. salida de entero a la salida estándar en Haskell
- 16. Formateo de la salida
- 17. Tipos de iterador: Salida vs. Entrada vs. Reenviar vs. Acceso aleatorio Iterador
- 18. conseguir el estado de salida y la salida de shell_exec()
- 19. Salida de la función de redireccionamiento a/dev/null
- 20. Salida de Ruby en la misma línea que la salida anterior
- 21. C# - ¿Cómo puedo pasar una referencia a una función que requiere una variable de salida?
- 22. Hashing una función python para regenerar la salida cuando se modifica la función
- 23. ¿Cómo puedo obtener una referencia a una secuencia de salida que escribe en la ventana de "salida" de Visual Studio?
- 24. Python: ¿salida de funciones?
- 25. ¿Cómo se ejecuta una función de salida en C++
- 26. salida a la misma línea que sobrescribe la salida anterior? python (2.5)
- 27. ¿Cómo devuelvo una función como valor de salida en MATLAB?
- 28. la salida de un procedimiento almacenado
- 29. ASPX que devuelve una imagen - ¿Caché de salida disponible?
- 30. ¿Log de la salida de IPython?
La idea es buena, pero no creo que necesite: T * operator ->() {return & m; } Y debe derivar de stl :: output_iterator Con esta implementación, se ejecuta una copia de T en cada asignación a través del iterador de salida. ¿Hay alguna manera de evitar eso? –