2010-02-22 14 views
21

He escrito toneladas de funciones operator<<(std::ostream &, const T &) - son increíblemente útiles.¿Alguien realmente usa operadores de extracción de flujo?

nunca he escrito una función operator>>(std::istream &, T &) en código real o incluso utilicé los operadores de extracción de los tipos predefinidos (OK, tal vez para std::string). ¿Son apropiados solo para programas de ejemplo cortos y libros de texto? ¿Es operator>> una característica fallida de C++?

Las preguntas se han preguntado sobre safely overloading stream operators. Lo que me pregunto es si alguien hace esto en la práctica.

Incluso para algo simple como reading input from a file in C++ No puedo sugerir usar operator>>. Es muy difícil escribir código sólido para detectar y manejar errores en la entrada (o no sé cómo).

Si no está de acuerdo, muestre un buen ejemplo del uso de operator>>, quizás respondiendo la última pregunta a la que me he vinculado.


Wrapup: Gracias por las respuestas a todos, muchas buenas opiniones. La respuesta de Manuel me hizo reconsiderar mi renuencia a usar op>>, así que acepté esa.

+0

Debe definir 'op >>' si es compatible con 'lexical_cast'. (http://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm). – kennytm

Respuesta

8

Creo que los operadores de extractor de flujo pueden ser muy útiles cuando se combinan con algoritmos STL como std::copy y con la clase std::istream_iterator.

Lea this answer para ver de lo que estoy hablando.

+0

Me gusta esa técnica. Tendré que intentarlo alguna vez. – Dan

3

Los valores se imprimen con más frecuencia que la lectura, por lo que operator<< se usa con más frecuencia que operator>>. Sin embargo, si desea leer valores, operator>> es útil.

Que debe comprobar si hay errores no es específico de operator>>, obviamente también cualquier otra forma de leer los valores tendrá que detectar la entrada no válida de alguna manera.

0

Hice un uso intensivo del operador < < para ensamblar listas de instrucciones de clasificación, campos en vistas de bases de datos, etc. en mi API de base de datos OOFILE.

Por alguna razón, un gran número de usuarios consideran que es intuitivo utilizar el operador >> a append a sort field which was a reverse sort. No sé quién lo sugirió en primer lugar, pero atrajo a suficientes personas que lo hizo en la API.

por ejemplo:

dbSorter arcSort; // declare a sorter 
arcSort << reverse(Date) << FileName; // "normal" way to specify two sort fields 
arcSort >> Date << FileName; // shorthand way that evolved to specify 

También hicimos uso convencional del operador >> para analizar toda una dbTable de una corriente.

+0

OK, pero eso no es un extractor istream. He usado op >> para escribir el código de cálculo de referencias, donde tuve control total sobre la entrada/salida y cualquier error fue fatal. Pero nunca me pareció útil para el procesamiento de texto. – Dan

+0

Me acabo de corregir a mí mismo: OOFILE usa el patrón convencional de operador >> llamando a un método de inserción virtual para tablas y campos. –

1

Operador >> es básicamente deserialización. En mi experiencia limitada y anecdótica, la mayoría de serialización/deserialización en C++ se implementa en un nivel más bajo que la biblioteca de la secuencia. No tiene que implementarse en un nivel inferior, simplemente lo es.

La implementación de la deserialización personalizada no siempre es un problema trivial, pero es probable que se encuentre con los mismos problemas, incluso si no lo implementa con la sintaxis de extracción de flujo.

Aquí hay un uso cheezy del operador de extracción de flujo que es al menos marginalmente útil: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

En este ámbito limitado, parece que el uso correcto es bastante simple.

+0

Ese es un ejemplo interesante, porque pone una 'cadena' en un' istringstream'. La consecuencia es que si se produce un error de análisis, la entrada original se puede mostrar al usuario. Vs. si el código estaba leyendo directamente de un 'istream', en el momento en que ocurrió la falla, es demasiado tarde para mostrar la entrada incorrecta. – Dan

+0

Las transmisiones de archivos y de red también son ejemplos útiles. Implementar cualquier tipo de deserialización en el nivel de flujo de bytes va a ser complicado, a menos que sus necesidades sean muy básicas. Para necesidades más grandes, debe diseñar un protocolo y luego implementarlo. Se puede diseñar el manejo de errores específicos (y tal vez la recuperación de errores y/o la redundancia de datos), en cuyo caso el código será obvio. –

6

Sí, utilizo el operador >> (aunque no tan frecuentemente como el operador < <).Es muy útil para analizar tipos definidos por el usuario en sus respectivos objetos y, por lo tanto, centralizar el análisis y el procesamiento de errores necesarios. También es muy útil para analizar la representación de cadena de un tipo enumerado.

Por ejemplo, considere un tipo enumerado que representa una fruta. Puede usar operator >> para analizar una cadena (como "apple", "banana", etc.) para obtener el valor de enumeración correcto.

std::istream &operator>>(std::istream &is, Fruit &fruit) 
{ 
    std::string str; 
    is >> str; 
    if (str == "apple") 
     fruit = APPLE; 
    else if (str == "banana") 
     fruit = BANANA; 
    // other fruits 
    else 
     is.setstate(std::ios::failbit); 
    return is; 
} 

Tenga en cuenta también el uso del método setstate en el istream para establecer el estado de fallo de la corriente cuando se encuentra una secuencia desconocida. Al utilizar este operador, se puede comprobar la failstate de la corriente de la siguiente manera:

Fruit fruit; 
std::cin >> fruit; 
if (std::cin.fail()) 
    std::cout << "Error: Unknown Fruit!" << std::endl; 
2

nunca escribirlas, y muy rara vez utilizan los "built-in". Los operadores de extracción son bastante inútiles para leer las entradas interactivas de los usuarios, porque es demasiado fácil que una transmisión falle. Escribir una rutina de análisis personalizada es casi siempre más fácil y más robusto. Y cuando se trata de serialización, si quiero guardar algo como texto, lo hago en un formato estándar de la industria como XML, que los operadores de extracción son especialmente inadecuados para leer. De lo contrario, almaceno los datos en una base de datos o en un archivo binario, que una vez más son inadecuados para su uso con extractores.

2

operator>> es útil para convertir números en forma de texto en una representación interna.

También puede ser útil en la carga de datos para objetos. A diferencia de scanf, que no se puede sobrecargar para diferentes tipos, los objetos pueden sobrecargar operator>>. Por lo tanto, proporciona más ocultación de datos para cargar objetos, no es necesario conocer la representación interna para leer datos en el objeto.

Cuestiones relacionadas