Otros me han dicho que escribir using namespace std;
en código es incorrecto, y que debería usar std::cout
y std::cin
directamente en su lugar.
¿Por qué se using namespace std;
considera una mala práctica? ¿Es ineficiente o corre el riesgo de declarar variables ambiguas (variables que comparten el mismo nombre que una función en el std
espacio de nombres)? ¿Afecta el rendimiento?
c++
namespaces
std
using-directives
c++-faq
akbiggs
fuente
fuente
std::literals::chrono_literals
,Poco::Data:Keywords
,Poco::Units
y otras cosas que se ocupará de los literales o trucos de legibilidad. Siempre que esté en el encabezado o en los archivos de implementación. Supongo que podría estar bien en el ámbito de una función, pero aparte de los literales y demás, no es útil.Respuestas:
Esto no está relacionado con el rendimiento en absoluto. Pero considere esto: está utilizando dos bibliotecas llamadas Foo y Bar:
Todo funciona bien, y puedes llamar
Blah()
desde Foo yQuux()
desde Bar sin problemas. Pero un día se actualiza a una nueva versión de Foo 2.0, que ahora ofrece una función llamadaQuux()
. Ahora tienes un conflicto: Foo 2.0 y Bar importanQuux()
en tu espacio de nombres global. Esto requerirá un esfuerzo para solucionarlo, especialmente si los parámetros de la función coinciden.Si hubiera usado
foo::Blah()
ybar::Quux()
, entonces la introducción defoo::Quux()
habría sido un no evento.fuente
#define
es que no se limita a los espacios de nombres, sino que pisotea todo el código base. Un alias de espacio de nombres es lo que quieres.Estoy de acuerdo con todo lo que Greg escribió , pero me gustaría agregar: ¡Incluso puede ser peor de lo que Greg dijo!
Library Foo 2.0 podría introducir una función,
Quux()
que es una coincidencia inequívocamente mejor para algunas de sus llamadasQuux()
quebar::Quux()
su código llamado durante años. Entonces su código aún se compila , pero silenciosamente llama a la función incorrecta y hace dios sabe qué. Eso es tan malo como las cosas pueden ponerse.Tenga en cuenta que el
std
espacio de nombres tiene toneladas de identificadores, muchos de los cuales son muy más comunes (pienselist
,sort
,string
,iterator
, etc.) que son muy probable que aparezca en otro código, también.Si considera que esto es poco probable: se hizo una pregunta aquí en Stack Overflow en la que sucedió más o menos exactamente (función incorrecta llamada debido al
std::
prefijo omitido ) aproximadamente medio año después de que di esta respuesta. Aquí hay otro ejemplo más reciente de tal pregunta. Entonces este es un problema real.Aquí hay un punto de datos más: Hace muchos, muchos años, también me resultaba molesto tener que prefijar todo desde la biblioteca estándar con
std::
. Luego trabajé en un proyecto en el que se decidió al principio que tanto lasusing
directivas como las declaraciones están prohibidas, excepto los ámbitos de 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 acordamos que en realidad hizo que el código fuera más legible . Hay una razón para eso: si le gusta la prosa más corta o más larga es subjetiva, pero los prefijos agregan objetivamente claridad al código. No solo el compilador, sino que 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 tuve curiosidad por saber con qué frecuencia el alcance de la función (permitido)
using
se usó realmente 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 probado, los desarrolladores no encuentran lostd::
suficientemente doloroso como para emplear el uso de directivas, incluso una vez cada 100 kLoC, incluso donde se permitió su uso.En pocas palabras: el prefijo explícito de todo no hace daño, toma muy poco tiempo acostumbrarse y tiene ventajas objetivas. En particular, hace que el código sea más fácil de interpretar por el compilador y por los lectores humanos, y ese probablemente debería ser el objetivo principal al escribir el código.
fuente
string
clase estándar , y aparentemente cada biblioteca tenía la suya. Decirle qué: seguiremos escribiendo nuestro códigostd::
, y puede ejecutar nuestro códigogrep -v std:: | vim
cuando lo esté navegando. O puede enseñarle a su editor questd::
es una palabra clave que debe tener el mismo color que el color de fondo. Lo que sea que funcione.std::
sea perjudicial en absoluto. Lleva información muy importante (es decir, "lo que viene después es parte de la biblioteca estándar", y sigue siendo un prefijo bastante corto y compacto. La mayoría de las veces, no es ningún problema. A veces, tiene algunas líneas de código donde se necesita hacer referencia a símbolos específicos en elstd
espacio de nombres mucho, y luego unausing
. declaración en la que resuelve el alcance particular el problema muy bien, pero en el caso general, no es el ruido, que transmite información valiosa , además de la eliminación de ambigüedades.std::
, sé que serástd::
sin tener que pensarlo. Si veostring
olist
omap
por ellos mismos, me pregunto un poco.vector
,transform
odistance
. Y esos son solo ejemplos de los muchos nombres muy comunes utilizados en la biblioteca estándar. Sugerir no usarlos por miedo o por una opinión sesgada de la función de espacio de nombres que es una parte integral de C ++ es bastante contraproducente.El problema con la colocación
using namespace
de los archivos de encabezado de sus clases es que obliga a cualquiera que quiera usar sus clases (al incluir sus archivos de encabezado) a 'usar' (es decir, ver todo) esos otros espacios de nombres.Sin embargo, puede sentirse libre de poner una declaración de uso en sus archivos (privados) * .cpp.
Tenga en cuenta que algunas personas no están de acuerdo con mi dicho "siéntase libre" de esta manera, porque aunque una
using
declaración en un archivo cpp es mejor que en un encabezado (porque no afecta a las personas que incluyen su archivo de encabezado), piensan que todavía no lo es bueno (porque dependiendo del código podría dificultar el mantenimiento de la implementación de la clase). Esta entrada de C ++ Super-FAQ dice:Las preguntas frecuentes sugieren dos alternativas:
Una declaración de uso:
Simplemente escribiendo std ::
fuente
Recientemente me encontré con una queja sobre Visual Studio 2010 . Resultó que casi todos los archivos fuente tenían estas dos líneas:
Muchas características de Boost están entrando en el estándar C ++ 0x, y Visual Studio 2010 tiene muchas características de C ++ 0x, por lo que de repente estos programas no se estaban compilando.
Por lo tanto, evitar
using namespace X;
es una forma de preparar el futuro, una forma de asegurarse de que un cambio en las bibliotecas y / o los archivos de encabezado en uso no va a romper un programa.fuente
using
fuera de una definición de función y rara vez usousing namespace
en absoluto.Versión corta: no use
using
declaraciones o directivas globales en los archivos de encabezado. Siéntase libre de usarlos en los archivos de implementación. Esto es lo que Herb Sutter y Andrei Alexandrescu tienen que decir sobre este tema en los Estándares de codificación C ++ (negrita para el énfasis es mío):fuente
using
nunca debe aparecer en un encabezado, no estoy tan convencido de la licencia gratuita para colocarusing namespace xyz;
en cualquier parte de su código, especialmente sixyz
es asístd
. Utilizo elusing std::vector;
formulario, ya que solo extrae un solo elemento del espacio de nombres en un alcance pseudo-global, lo que lleva a un riesgo mucho menor de colisión.using namespace
es malo comogoto
es malo. Ambos tienen usos válidos, pero 999 de cada 1000 veces se usarán incorrectamente. Entonces, sí, conusing namespace
la fuente no contaminará el espacio de nombres de otras inclusiones, ordenado. Pero aún así no lo protegerá contra la "diversión" que surge deusing namespace Foo
+using namespace Bar
con su llamada (Foo implícito: :)baz(xyz)
y de repente la ruptura del código (sin cambios relacionados) solo porqueBar::baz()
se agregó en alguna parte, lo que resulta ser mejor coincidir (y por lo tanto ahora se vuelve a llamar en su lugar)Uno no debería usar la
using
directiva en el ámbito global, especialmente en los encabezados. Sin embargo, hay situaciones en las que es apropiado incluso en un archivo de encabezado:Esto es mejor que la calificación explícita (
std::sin
,std::cos
...), porque es más corto y tiene la capacidad de trabajar con tipos de punto flotante definidos por el usuario (a través de una búsqueda dependiente de argumentos (ADL)).fuente
using std::cos;
,using std::sin
, Etc. El problema es que aunque ningún bien diseñadouserlib
va a tener susin
ycos
dentro de su propio espacio de nombres, así, por lo que esto no le ayuda. (A menos que haya unausing namespace userlib
plantilla anterior a esta y que sea tan mala comousing namespace std
, y el alcance no esté limitado). Además, la única función como esta que veo que ocurra esswap
, y en tales casos recomendaría simplemente crear una plantilla especializaciónstd::swap
y evitar todo el problema.template<typename T> void swap(MyContainer<T>&, MyContainer<T>&)
(No existe una especialización parcial de plantilla de función (FTPS), por lo que a veces es necesario recurrir a la sobrecarga.x
tiene uno o más "espacios de nombres asociados" (por ejemplo, si se define ennamespace userlib
) entonces cualquier llamada a la función que se ve comocos(x)
va , además, buscar en esos espacios de nombres - y sin ningúnusing namespace userlib;
antemano que sea necesaria. Zan Lynx tiene razón (y la búsqueda de nombres en C ++ es bizantina ...)No lo use globalmente
Se considera "malo" solo cuando se usa globalmente . Porque:
using namespace xyz
.using namespace std
es posible que no esté al tanto de todas las cosas que agarra, y cuando agrega otro#include
o pasa a una nueva revisión de C ++, puede obtener conflictos de nombres que no conocía.Puedes usarlo localmente
Continúe y utilícelo localmente (casi) libremente. Esto, por supuesto, evita que repitas
std::
, y la repetición también es mala.Un modismo para usarlo localmente
En C ++ 03 había un modismo - código repetitivo - para implementar una
swap
función para sus clases. Se sugirió que realmente usaras un localusing namespace std
, o al menosusing std::swap
:Esto hace la siguiente magia:
std::swap
paravalue_
, es decirvoid std::swap(int, int)
.void swap(Child&, Child&)
implementada, el compilador la elegirá.void std::swap(Child&,Child&)
e intentará intercambiarlas.Con C ++ 11 ya no hay razón para usar este patrón. La implementación de
std::swap
se cambió para encontrar una posible sobrecarga y elegirla.fuente
swap
en primer lugar ya no es tan importante en C ++ 11, ya questd::swap
es más flexible (usa semántica de movimiento). Perostd::swap
elegir automáticamente su propio intercambio personalizado, eso es absolutamente nuevo para mí (y realmente no lo creo).using std::swap;
lugar deusing namespace std;
. El idioma más específico tiene menos efectos secundarios y, por lo tanto, hace que el código sea más fácil de mantener.swap
, y se cambiaron otros lugares en el estándar para decir que llamanswap
así (NB, como se indicó anteriormente,using std::swap
es la forma correcta, nousing namespace std
). Perostd::swap
sí fue enfáticamente no cambió a encontrar algún otroswap
y utilizarlo. Sistd::swap
se llama,std::swap
se acostumbra.using std::swap
embargo, podría ser más prudente escribir localmente para reducir el espacio de nombres local y al mismo tiempo crear código autodocumentado. Usted está raramente siempre interesada en todo el espacio de nombres std, por lo que acaba de salir a escoger las piezas que estén interesados.Si importa los archivos de cabecera derecha de repente tiene nombres como
hex
,left
,plus
ocount
en su ámbito global. Esto puede ser sorprendente si no sabe questd::
contiene estos nombres. Si también intenta usar estos nombres localmente, puede generar bastante confusión.Si todo el material estándar está en su propio espacio de nombres, no tiene que preocuparse por las colisiones de nombres con su código u otras bibliotecas.
fuente
distance
. Todavía prefiero nombres no calificados siempre que sea prácticamente posible, ya que eso aumenta la legibilidad para mí. Además, creo que el hecho de que generalmente no califiquemos las cosas en el discurso oral y que estemos dispuestos a pasar tiempo resolviendo posibles ambigüedades, significa que tiene valor poder entender de qué se está hablando sin calificaciones, y se aplica a la fuente. código que significa que está estructurado de tal manera que está claro de qué se trata, incluso sin calificaciones.<iomanip>
. Aún así, buen punto.Otra razón es la sorpresa.
Si veo
cout << blah
, en lugar destd::cout << blah
pensar: ¿Qué es estocout
? ¿Es lo normalcout
? ¿Es algo especial?fuente
cout
es un mal ejemplo porque todos lo reconocen. Pero imaginafuture
en una aplicación financiera. ¿Es un contrato para comprar o vender algo en una fecha específica? No, no lo es. Si el código dijerastd::future
que no te confundirías tan fácilmente.Los programadores experimentados usan lo que resuelve sus problemas y evitan lo que crea nuevos problemas, y evitan las directivas de uso de nivel de archivo de encabezado por esta razón exacta.
Los programadores experimentados también intentan evitar la calificación completa de los nombres dentro de sus archivos fuente. Una razón menor para esto es que no es elegante escribir más código cuando menos código es suficiente a menos que haya buenas razones . Una razón importante para esto es desactivar la búsqueda dependiente de argumentos (ADL).
¿Cuáles son estas buenas razones ? Algunas veces los programadores quieren desactivar ADL explícitamente, otras veces quieren desambiguar.
Entonces los siguientes están bien:
fuente
Estoy de acuerdo en que no debe usarse globalmente, pero no es tan malo usarlo localmente, como en a
namespace
. Aquí hay un ejemplo de "El lenguaje de programación C ++" :En este ejemplo, resolvimos posibles conflictos de nombres y ambigüedades derivados de su composición.
Los nombres declarados explícitamente allí (incluidos los nombres declarados por declaraciones de uso como
His_lib::String
) tienen prioridad sobre los nombres accesibles en otro ámbito mediante una directiva de uso (using namespace Her_lib
).fuente
También lo considero una mala práctica. ¿Por qué? Solo un día pensé que la función de un espacio de nombres es dividir cosas, por lo que no debería estropearlo arrojando todo en una bolsa global.
Sin embargo, si a menudo uso 'cout' y 'cin', escribo:
using std::cout; using std::cin;
en el archivo .cpp (nunca en el archivo de encabezado, ya que se propaga con#include
). Creo que nadie cuerdo nunca nombrará una secuenciacout
ocin
. ;)fuente
Es bueno ver el código y saber lo que hace. Si veo
std::cout
, sé que ese es elcout
flujo de lastd
biblioteca. Si veo,cout
entonces no lo sé. Que podría ser lacout
corriente de lastd
biblioteca. O podría haberint cout = 0;
diez líneas más arriba en la misma función. O unastatic
variable nombradacout
en ese archivo. Podría ser cualquier cosa.Ahora tome una base de código de un millón de líneas, que no es particularmente grande, y está buscando un error, lo que significa que sabe que hay una línea en este millón de líneas que no hace lo que se supone que debe hacer.
cout << 1;
podría leer unstatic int
nombrecout
, desplazarlo un poco hacia la izquierda y tirar el resultado. Buscando un error, tendría que comprobarlo. ¿Puedes ver cómo realmente prefiero verstd::cout
?Es una de estas cosas que parecen una muy buena idea si eres maestro y nunca tuviste que escribir y mantener ningún código para vivir. Me encanta ver el código donde (1) sé lo que hace; y (2) estoy seguro de que la persona que lo escribió sabía lo que hace.
fuente
Se trata de gestionar la complejidad. El uso del espacio de nombres extraerá cosas que no desea y, por lo tanto, posiblemente dificultará la depuración (lo digo, posiblemente). Usar std :: por todas partes es más difícil de leer (más texto y todo eso).
Caballos para cursos: gestione su complejidad de la mejor manera posible y siéntase capaz.
fuente
Considerar
Tenga en cuenta que este es un ejemplo simple. Si tiene archivos con 20 inclusiones y otras importaciones, tendrá que pasar por un montón de dependencias para resolver el problema. Lo peor de todo es que puede obtener errores no relacionados en otros módulos dependiendo de las definiciones que entren en conflicto.
No es horrible, pero se ahorrará dolores de cabeza al no usarlo en archivos de encabezado o en el espacio de nombres global. Probablemente esté bien hacerlo en ámbitos muy limitados, pero nunca he tenido problemas para escribir los cinco caracteres adicionales para aclarar de dónde provienen mis funciones.
fuente
Debe poder leer el código escrito por personas que tienen diferentes estilos y opiniones de mejores prácticas que usted.
Si solo estás usando
cout
, nadie se confunde. Pero cuando tiene muchos espacios de nombres volando y ve esta clase y no está exactamente seguro de lo que hace, tener el espacio de nombres explícito actúa como una especie de comentario. Puede ver a primera vista, "oh, esta es una operación del sistema de archivos" o "eso está haciendo cosas de red".fuente
Usar muchos espacios de nombres al mismo tiempo es obviamente una receta para el desastre, pero usar SOLO espacios de nombres
std
y solo espacios de nombresstd
no es tan importante en mi opinión porque la redefinición solo puede ocurrir por su propio código ...Tan solo considérelas funciones como nombres reservados como "int" o "clase" y eso es todo.
La gente debería dejar de ser tan anal al respecto. Tu maestra tenía razón todo el tiempo. Simplemente use UN espacio de nombres; ese es el objetivo de usar espacios de nombres en primer lugar. Se supone que no debe usar más de uno al mismo tiempo. A menos que sea tuyo. Entonces, nuevamente, la redefinición no sucederá.
fuente
min
,end
yless
aparecen en elstd::
espacio de nombres. Pero más, ahora questd::
tiene miles de símbolos, es útil para el lector saber de dónde proviene un nuevo símbolo que tal vez no conozcan.Estoy de acuerdo con los demás aquí, pero me gustaría abordar las preocupaciones con respecto a la legibilidad: puede evitar todo eso simplemente usando typedefs en la parte superior de su archivo, función o declaración de clase.
Usualmente lo uso en mi declaración de clase ya que los métodos en una clase tienden a tratar con tipos de datos similares (los miembros) y un typedef es una oportunidad para asignar un nombre que sea significativo en el contexto de la clase. Esto realmente ayuda a la legibilidad en las definiciones de los métodos de clase.
y en la implementación:
Opuesto a:
o:
fuente
Un ejemplo concreto para aclarar la preocupación. Imagine que tiene una situación en la que tiene dos bibliotecas
foo
ybar
cada una con su propio espacio de nombres:Ahora supongamos que usa
foo
ybar
juntos en su propio programa de la siguiente manera:En este punto todo está bien. Cuando ejecuta su programa, "hace algo". Pero luego actualizas
bar
y digamos que ha cambiado para ser así:En este punto, obtendrá un error del compilador:
Por lo tanto, deberá realizar algunas tareas de mantenimiento para aclarar que 'a' significaba
foo::a
. Eso no es deseable, pero afortunadamente es bastante fácil (solo agreguefoo::
frente a todas las llamadas aa
que el compilador marca como ambiguo).Pero imagine un escenario alternativo donde la barra cambió en su lugar para verse así:
En este punto, su llamado a
a(42)
unirse repentinamente a,bar::a
enfoo::a
lugar de hacer "algo", hace "algo completamente diferente". No hay advertencia del compilador ni nada. Su programa comienza silenciosamente a hacer algo completamente diferente que antes.Cuando usa un espacio de nombres, está arriesgando un escenario como este, por lo que las personas se sienten incómodas al usar espacios de nombres. Cuantas más cosas hay en un espacio de nombres, mayor es el riesgo de conflicto, por lo que las personas pueden sentirse aún más incómodas al usar el espacio de nombres
std
(debido a la cantidad de cosas en ese espacio de nombres) que otros espacios de nombres.En última instancia, se trata de una compensación entre la capacidad de escritura y la fiabilidad / mantenibilidad. La legibilidad también puede tener en cuenta, pero podría ver argumentos para eso yendo en cualquier dirección. Normalmente diría que la confiabilidad y la mantenibilidad son más importantes, pero en este caso pagará constantemente el costo de escritura por un impacto bastante raro de confiabilidad / mantenibilidad. La "mejor" compensación determinará su proyecto y sus prioridades.
fuente
Un espacio de nombres es un ámbito con nombre. Los espacios de nombres se utilizan para agrupar declaraciones relacionadas y para mantener elementos separados por separado. Por ejemplo, dos bibliotecas desarrolladas por separado pueden usar el mismo nombre para referirse a diferentes elementos, pero un usuario aún puede usar ambos:
Repetir un nombre de espacio de nombres puede ser una distracción tanto para lectores como para escritores. En consecuencia, es posible afirmar que los nombres de un espacio de nombres en particular están disponibles sin calificación explícita. Por ejemplo:
Los espacios de nombres proporcionan una herramienta poderosa para la gestión de diferentes bibliotecas y de diferentes versiones de código. En particular, ofrecen al programador alternativas de cuán explícito hacer una referencia a un nombre no local.
Fuente: Una descripción general del lenguaje de programación C ++ por Bjarne Stroustrup
fuente
Un ejemplo donde
using namespace std
arroja un error de compilación debido a la ambigüedad de la cuenta, que también es una función en la biblioteca de algoritmos.fuente
::count
--problema resuelto. Por lo general, tendrá más cosas del espacio de nombres estándar que de cualquier otro lugar, por lo tanto, mantener la directiva de uso del espacio de nombres podría ahorrarle escribir.No empeora el rendimiento de su software o proyecto. La inclusión del espacio de nombres al comienzo de su código fuente no está mal. La inclusión de la
using namespace std
instrucción varía según sus necesidades y la forma en que está desarrollando el software o proyecto.El
namespace std
contiene funciones y variables estándar el C ++. Este espacio de nombres es útil cuando a menudo usaría las funciones estándar de C ++.Algunas personas han dicho que es una mala práctica incluir
using namespace std
en sus archivos fuente porque está invocando desde ese espacio de nombres todas las funciones y variables. Cuando desee definir una nueva función con el mismo nombre que otra función contenida en lanamespace std
, sobrecargaría la función y podría producir problemas debido a la compilación o ejecución. No se compilará ni ejecutará como espera.fuente
No creo que sea necesariamente una mala práctica en todas las condiciones, pero debes tener cuidado cuando la uses. Si está escribiendo una biblioteca, probablemente debería usar los operadores de resolución de alcance con el espacio de nombres para evitar que su biblioteca choque con otras bibliotecas. Para el código de nivel de aplicación, no veo nada de malo en ello.
fuente
"¿Por qué está 'usando el espacio de nombres std;' considerado una mala práctica en C ++? "
Lo digo al revés: ¿por qué escribir cinco caracteres adicionales es engorroso para algunos?
Considere, por ejemplo, escribir una pieza de software numérico. ¿Por qué incluso consideraría contaminar mi espacio de nombres global cortando "std :: vector" general a "vector" cuando "vector" es uno de los conceptos más importantes del dominio del problema?
fuente
cout << hex << setw(4) << i << endl;
es más fácil de leer questd::cout << std::hex << std::setw(4) << i << std::endl;
std::map<std::string,std::pair<std::string,std::string>>
es horrible en comparación conmap<string,pair<string,string>>
.Estoy de acuerdo con los demás: está pidiendo conflictos de nombres, ambigüedades y el hecho es que es menos explícito. Si bien puedo ver el uso de
using
, mi preferencia personal es limitarlo. También consideraría fuertemente lo que otros señalaron:Si desea encontrar un nombre de función que podría ser un nombre bastante común, pero solo desea encontrarlo en el
std
espacio de nombres (o al revés, desea cambiar todas las llamadas que no están en el espacio de nombresstd
, espacio de nombresX
, ...), entonces, ¿cómo propones hacer esto?Podrías escribir un programa para hacerlo, pero ¿no sería mejor pasar tiempo trabajando en tu proyecto en lugar de escribir un programa para mantenerlo?
Personalmente, en realidad no me importa el
std::
prefijo. Me gusta más el aspecto que no tenerlo. No sé si eso es porque es explícito y me dice "este no es mi código ... estoy usando la biblioteca estándar" o si es otra cosa, pero creo que se ve mejor. Esto podría ser extraño dado que recientemente ingresé a C ++ (usé y sigo haciendo C y otros lenguajes durante mucho más tiempo y C es mi lenguaje favorito de todos los tiempos, justo encima del ensamblaje).Hay otra cosa, aunque está algo relacionada con lo anterior y lo que otros señalan. Si bien esto podría ser una mala práctica, a veces me reservo
std::name
para la versión estándar de la biblioteca y el nombre para la implementación específica del programa. Sí, de hecho, esto podría morderte y morderte duro, pero todo se reduce a que comencé este proyecto desde cero, y soy el único programador para ello. Ejemplo: lo sobrecargostd::string
y lo llamostring
. Tengo adiciones útiles. Lo hice en parte debido a mi tendencia de C y Unix (+ Linux) hacia los nombres en minúsculas.Además de eso, puede tener alias de espacio de nombres. Aquí hay un ejemplo de dónde es útil que podría no haber sido mencionado. Yo uso el estándar C ++ 11 y específicamente con libstdc ++. Bueno, no tiene
std::regex
soporte completo . Claro, se compila, pero arroja una excepción en el sentido de que es un error al final del programador. Pero es falta de implementación.Así que así es como lo resolví. Instale la expresión regular de Boost y vincúlela. Luego, hago lo siguiente para que cuando libstdc ++ lo haya implementado por completo, solo necesito eliminar este bloque y el código permanece igual:
No discutiré si es una mala idea o no. Sin embargo, argumentaré que lo mantiene limpio para mi proyecto y al mismo tiempo lo hace específico: es cierto, tengo que usar Boost, pero lo estoy utilizando como libstdc ++ eventualmente lo tendrá. Sí, comenzar su propio proyecto y comenzar con un estándar (...) al principio ayuda mucho al mantenimiento, el desarrollo y todo lo relacionado con el proyecto.
Solo para aclarar algo: en realidad no creo que sea una buena idea usar el nombre de una clase / lo que sea en el STL deliberadamente y más específicamente en lugar de. La cadena es la excepción (ignore el primero, el anterior o el segundo aquí, haga un juego de palabras si es necesario) para mí, ya que no me gustó la idea de 'String'.
Tal como están las cosas, todavía estoy muy sesgado hacia C y hacia C ++. Ahorrando detalles, gran parte de lo que trabajo encaja más en C (pero fue un buen ejercicio y una buena manera de hacerme a. Aprender otro idioma yb. Tratar de no estar menos predispuesto contra el objeto / clases / etc., lo que tal vez sea mejor dicho como menos cerrado de mente, menos arrogante y más tolerante). Pero lo que es útil es lo que algunos ya sugirieron: de hecho uso la lista (es bastante genérica, ¿no es así?), Y clasifico (lo mismo) para nombrar dos que causarían un choque de nombres si lo hiciera
using namespace std;
, y así para ello prefiero ser específico, tener el control y saber que si pretendo que sea el uso estándar, tendré que especificarlo. En pocas palabras: no se permite suponer.Y en cuanto a hacer parte de la expresión regular de Boost
std
. Lo hago para una futura integración y, una vez más, admito que esto es parcial, no creo que sea tan feo comoboost::regex:: ...
. De hecho, eso es otra cosa para mí. Hay muchas cosas en C ++ que todavía tengo que aceptar completamente en miradas y métodos (otro ejemplo: plantillas variadas versus argumentos var [¡aunque admito que las plantillas variadas son muy, muy útiles!]). Incluso aquellos que sí acepto fueron difíciles, y todavía tengo problemas con ellos.fuente
std
espacio de nombres es un comportamiento indefinido y, por lo tanto, nunca debe hacerse.Según mi experiencia, si tiene varias bibliotecas que usan say
cout
, pero para un propósito diferente, puede usar el incorrectocout
.Por ejemplo, si escribo en,
using namespace std;
yusing namespace otherlib;
y el tipo simplementecout
(que pasa a ser en ambos), en lugar destd::cout
(o'otherlib::cout'
), es posible utilizar el equivocado, y obtener errores. Es mucho más efectivo y eficiente de usarstd::cout
.fuente
Con los identificadores importados no calificados, necesita herramientas de búsqueda externas como grep para averiguar dónde se declaran los identificadores. Esto dificulta el razonamiento sobre la corrección del programa.
fuente
Depende de dónde se encuentre. Si es un encabezado común, está disminuyendo el valor del espacio de nombres al fusionarlo en el espacio de nombres global. Tenga en cuenta que esta podría ser una buena forma de hacer que los módulos sean globales.
fuente
Esta es una mala práctica, a menudo conocida como contaminación global del espacio de nombres. Pueden surgir problemas cuando más de un espacio de nombres tiene el mismo nombre de función con firma, entonces será ambiguo que el compilador decida a cuál llamar y todo esto se puede evitar cuando se especifica el espacio de nombres con su llamada de función como
std::cout
. Espero que esto ayude. :)fuente
Para responder a su pregunta, lo veo prácticamente de esta manera: muchos programadores (no todos) invocan el espacio de nombres estándar. Por lo tanto, uno debe tener la costumbre de NO usar cosas que afecten o usen los mismos nombres que los que están en el espacio de nombres estándar. Es un gran acuerdo, pero no tanto en comparación con el número de posibles palabras coherentes y seudónimos que pueden surgir estrictamente hablando.
Quiero decir realmente ... decir "no confíes en que este esté presente" es solo configurarte para que confíes en que NO esté presente. Siempre tendrá problemas para tomar prestados fragmentos de código y repararlos constantemente. Simplemente mantenga sus cosas prestadas y definidas por el usuario en un alcance limitado como deberían ser y sea MUY respetuoso con los globales (honestamente, los globales casi siempre deberían ser el último recurso para los propósitos de "compilar ahora, cordura después"). Verdaderamente creo que es un mal consejo de tu maestro porque usar std funcionará tanto para "cout" como para "std :: cout" pero NO usar std solo funcionará para "std :: cout". No siempre tendrá la suerte de escribir todo su propio código.
NOTA: No se concentre demasiado en los problemas de eficiencia hasta que realmente aprenda un poco sobre cómo funcionan los compiladores. Con un poco de experiencia en la codificación, no tiene que aprender mucho sobre ellos antes de darse cuenta de cuánto pueden generalizar un buen código en algo simple. Tan simple como si escribieras todo en C. Un buen código es tan complejo como debe ser.
fuente
<algorithm>
por ejemplo, reinventar cosas ), parece un poco exagerado imaginar que las mismas personas puedan evitar esos identificadores de manera confiable. Mire su propio código y dígame que nunca tiene una variable o función llamadacount
. Odistance
, olog
,destroy
,launch
,visit
,beta
,sample
,messages
,clamp
,erase
,copy
,modulus
,left
, etc. Por no hablar de todos los identificadores aún no está enstd
que romperá su código cuando C ++ 35 sale ...