Biblioteca estándar de C++: ¿Cómo escribir contenedores para cout, cerr, cin y endl?

Resuelto Ashwin Nanjappa asked hace 14 años • 2 respuestas

No me gusta , using namespace stdpero también estoy cansado de tener que escribir std::delante de cada cout,, y . Entonces, pensé en darles nombres nuevos más cortos como este:cincerrendl

// STLWrapper.h

#include <iostream>
#include <string>

extern std::ostream& Cout;
extern std::ostream& Cerr;
extern std::istream& Cin;
extern std::string&  Endl;

// STLWrapper.cpp

#include "STLWrapper.h"

std::ostream& Cout = std::cout;
std::ostream& Cerr = std::cerr;
std::istream& Cerr = std::cin;
std::string _EndlStr("\n");
std::string& Endl = _EndlStr;

Esto funciona. Pero, ¿hay algún problema en lo anterior que me falta? ¿Existe una mejor manera de lograr lo mismo?

Ashwin Nanjappa avatar May 21 '10 11:05 Ashwin Nanjappa
Aceptado

Alex te ha dado una respuesta sobre cómo resolver sintácticamente ese problema. Sin embargo, quiero señalar otros dos argumentos respecto a esta cuestión:

  1. No importa si estás empleando una directiva de uso ( using namespace std) o su hermana menos malvada, una declaración de uso ( using std::cout), la sobrecarga puede llevar a sorpresas desagradables. No es mucha molestia escribir std::en comparación con pasar media noche depurando para descubrir que se llama a su código std::distance()en lugar de a su propia distance()función , solo porque cometió un pequeño error y std::distance()accidentalmente es una mejor coincidencia.

  2. Una línea de código se escribe una vez , pero, dependiendo de su vida útil, se lee decenas, cientos y, en algunos casos, incluso miles de veces . Así que el tiempo que lleva escribir una línea de código simplemente no importa en absoluto , lo importante es sólo el tiempo que lleva leer e interpretar una línea de código . Incluso si se necesita tres veces más tiempo para escribir una línea con todo lo adecuado std::, si hace que la lectura sea solo un 10% más rápida, aún así vale la pena.
    Entonces, la pregunta importante es: ¿ Es más fácil leer e interpretar una línea de código con todo el código std::en su lugar o es más difícil ? De otra respuesta :

    Aquí hay un dato más: Hace muchos, muchos años, también me resultaba molesto tener que anteponer todo lo de la biblioteca estándar con std::. Luego trabajé en un proyecto en el que se decidió desde el principio que tanto usinglas directivas como las declaraciones estaban prohibidas excepto en el ámbito de las funciones. ¿Adivina qué? A la mayoría de nosotros nos tomó muy pocas semanas acostumbrarnos a escribir el prefijo y después de algunas semanas más, la mayoría de nosotros incluso estuvo de acuerdo en que en realidad hacía que el código fuera más legible . (Hay una razón para esto: si le gusta la prosa más corta o más larga es subjetivo, pero los prefijos agregan objetivamente claridad al código. No solo al compilador, sino a usted también le resulta más fácil ver a qué identificador se hace referencia).

    En una década, ese proyecto creció hasta tener varios millones de líneas de código. Dado que estas discusiones surgen una y otra vez, una vez sentí curiosidad por saber con qué frecuencia usingse usaba realmente el alcance de función (permitido) en el proyecto. Busqué las fuentes y solo encontré una o dos docenas de lugares donde se usaba. Para mí, esto indica que, una vez que lo intentaron, a los desarrolladores no les resultó std::lo suficientemente doloroso emplear directivas de uso ni siquiera una vez cada 100 kLoC, incluso donde se permitía su uso .

    Creo que es triste que todos los libros y tutoriales que encuentres se salten std::, porque eso hace que la gente se acostumbre a leer el código de esa manera. Cuando enseñé C++ durante varios años (después de la experiencia mencionada anteriormente), les dije a mis alumnos que no quería ver ninguna usingdirectiva o declaración en su código. (La única excepción a esa regla es using std::swap, por cierto, que necesitará para detectar swap(a,b)sobrecargas fuera del espacio de nombres std). Una vez que se acostumbraron, no les importó y, cuando se les preguntó al respecto, dijeron que encontrar código sin std::prefijo confuso. Algunos incluso agregaron el std::prefijo al código que escribieron en un libro o tutorial que no lo tenía .

En pocas palabras: ¿Qué tiene de difícil escribir std::que todo el mundo se enoja tanto? Ya llevo más de 15 años haciéndolo y no me pierdo usingnada.

sbi avatar May 21 '2010 07:05 sbi

Por qué no

using std::cin;
using std::cout;

¿etcétera? Luego, en su código puede usar cin, couty así sucesivamente, sin inyectar accidentalmente el resto del stdespacio de nombres en su código.

Alex Martelli avatar May 21 '2010 04:05 Alex Martelli