39

Me han dicho en numerosas ocasiones es una mala practica usar using namespace std; en nuestros programas. Por lo tanto, debemos utilizar std::cout y std::cin, que es la forma mas adecuada.

¿Por qué es using namespace std; considera malo? ¿Es realmente muy ineficiente, o el riesgo de declaración de variables ambiguas (variables que comparten el mismo nombre que una función en el espacio de nombres std)? ¿o afecta al rendimiento notablemente?

eferion
  • 49,291
  • 5
  • 30
  • 72
Angel Angel
  • 9,623
  • 9
  • 37
  • 68

4 Answers4

42

Autor original

Greg Hewgill https://stackoverflow.com/users/893/greg-hewgill

El uso de using namespaceno está relacionado de ninguna forma con el rendimiento. Sin embargo considera el siguiente escenario: Estas utilizando dos bibliotecas llamadas Foo y Bar y en un momento dado decides importar los espacios de nombres:

using namespace foo;
using namespace bar;

Todo funciona bien, puedes llamar Bla() de Foo y a quux() de Bar y sin problemas.

Pero un día actualizas a una nueva versión de Foo 2.0 que ofrece una función llamada quux(). El resultado es tienes un conflicto: Tanto Foo 2.0 como Bar importan quux() en el espacio de nombres global. Corregir el error puede requerir bastante esfuerzo sobre todo si los parámetros de ambas funciones son iguales.

Si en vez de importar los espacios de nombres has utilizado foo::Bla() y bar::quux(), introduccir foo::quux() no requiere esfuerzos adicionales.

Autor original

sbi https://stackoverflow.com/users/140719/sbi

Estoy de acuerdo con todo lo que Greg escribió, pero me gustaría añadir un detalle que podría ser peor que el comentado por Greg:

La biblioteca Foo 2.0 podría introducir una función, bar::quux() que tendría la misma firma que la función orignal de la librería Bar. Lo que sucede entonces es que el código seguiría compilando pero de forma silenciosa podría pasar a llamar a la nueva función ubicada en Foo 2.0 en vez de a la función de Bar y las consecuencias derivadas de este efecto pueden ser totalmente impredecibles.

Ten en cuenta que el espacio de nombres std tiene toneladas de identificadores, muchos de los cuales son muy comunes (pensar en list, sort, string, iterator, etc.), y es muy probable que alguno de ellos acabe apareciendo repetido en otra librería.

Si alguien piensa que esto es algo bastante improbable no estaría de más comentar que ya hay al menos una pregunta en StackOverflow donde sucedió esto mismo (la función llamada no era la esperada debido a que se omitió el prefijo std) y la respuesta no apareció hasta después de un año.

Autor original

ChrisW https://stackoverflow.com/users/49942/chrisw

Creo que es malo ponerlo en los archivos de cabecera de sus clases, porque entonces se estaría obligando a cualquier persona que quiera utilizar sus clases (incluyendo sus archivos de cabecera) a importar también el resto de espacios de nombres.

Angel Angel
  • 9,623
  • 9
  • 37
  • 68
9

Depende de lo que quieras hacer y el tamaño del problema que estés resolviendo.

Si utilizas mucho la STL (librería estándar de C++), que es en muchos casos es una buena idea porque está bastante bien hecha, es bastante cómodo poner using namespace std; al principio y olvidarte de poner std::vector<TipoDato> cada vez que quieras declarar un vector de la STL.

El problema que tendrías con el using namespace std; es que si, por ejemplo, quisieras declarate algo con el nombre vector entraría en conflicto con el vector de la STL, y puede llevar a errores inesperados y costosos de corregir.

Esto también es válido para el ejemplo del cin y el cout que se plantea en la pregunta.

Para programas pequeños para aprender estas sutilezas del lenguaje no son importantes.

jpuriol
  • 353
  • 1
  • 3
  • 10
  • como norma general no es buena idea usar `using namespace std;` sino, más bien, importar únicamente aquello que necesitas en cada momento... y restringir su uso a los `cpp`... usar esto una cabecera debería ser motivo suficiente para suspender al alumno – eferion Jan 24 '18 at 21:51
  • Si mejor usarlo solo en los .cpp, pero insisto en que puede ser cómodo para no teclear demasiado. – jpuriol Jan 25 '18 at 17:06
  • no es algo que se inventase para no teclear demasiado sino para intentar que determinados codigos fuesen mas legibles... si hubiesen querido que escribieses menos habrian fusionado cabecera e implementación... entre otras cosas – eferion Jan 25 '18 at 17:14
8

Respuesta corta:

Colisión de nombres, por ejemplo si utilizas una libreria que define funciones con nombres genericos como, open, write o vector; estos colisionan con los nombres de la biblioteca estandard, por lo tanto seria buena practica tener los nombres de los simbolos (funciones) dentro de su namespace y asi los nombres dentro del namespace std, no colisionaran con estos previamente definidos

Considero que no es una mala practica si utilisas usign namespace std dentro de un contexto limitado, por ejemplo dentro de una funcion que utiliza exsesivamente el namespace std::.

Pero justo debajo de un #include<...es considerado una mala practica porque puedes "ensuciar" en namespace global.

StvKrl
  • 376
  • 2
  • 4
5

No afecta el rendimiento de tu proyecto, no se considera malo su inclusión en el código y su uso depende de las necesidades y la forma en que desarrolles tu proyecto.

En las bibliotecas estándar de las funciones de C y C++ se encuentran contenidas por el namespace std. Se considera útil nombrarlo al comienzo de tu fichero fuente cuando vayas a dar uso frecuente a las funciones de C y C++ estándares.

Cito al siguiente curso de C/C++:

26. Espacios con nombre.

El espacio "std" se usa en todas las bibliotecas estándar, de modo que todas las funciones y clases estándar se declaran y definen en ese espacio.

...

También es posible crear un espacio con nombre a lo largo de varios ficheros diferentes, de hecho eso es lo que se hace con el espacio std, que se define en todos los ficheros estándar.

...

Precisamente porque las bibliotecas estándar declaran todas sus variables, funciones, clases y objetos en el espacio std, es necesario usar las nuevas versiones de los ficheros de cabecera estándar: "iostream", "fstream", etc. Y en lo que respecta a las procedentes de C, hay que usar las nuevas versiones que comienzan por 'c' y no tienen extensión: "cstdio", "cstdlib", "cstring", etc...". Todas esas bibliotecas han sido rescritas en el espacio con nombre std.

Apéndice C: Bibliotecas estándar.

Todos los compiladores C y C++ disponen de ciertas bibliotecas de funciones estándar que facilitan el acceso a la pantalla, al teclado, a los discos, la manipulación de cadenas, y muchas otras cosas, de uso corriente.

Hay que decir que todas estas funciones no son imprescindibles, y de hecho no forman parte del C. Pueden estar escritas en C, de hecho en su mayor parte lo están, y muchos compiladores incluyen el código fuente de estas bibliotecas. Nos hacen la vida más fácil, y no tendría sentido pasarlas por alto.

Algunas personas indican que es una mala práctica porque durante el desarrollo de tu proyecto en C/C++, al utilizar el using namespace std estás tomando del espacio de nombre todo su contenido y al momento de que quieras crear una función con un nombre que ya aparezca dentro de las funciones o variables del namespace std; sobrecargando así una función ya existente y dando problemas a la hora de compilar o ejecutar.

Esto lo puedes ver mejor en la respuesta de este foro:

¿Usar "Using namespace std;" es mala práctica?

Básicamente porque se pueden confundir cosas, tampoco es común pero es posible.

...

Lo que pasa es que cuando tu declaras tu función sobrecargas (escribes encima) de la otra función y pierdes su funcionalidad, esto como gran problema de entrada.

CryogenicNeo
  • 960
  • 8
  • 16