¿Por qué" usar std de espacio de nombres " se considera una mala práctica?


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 considera using namespace std 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 espacio de nombres std)? ¿Afecta al rendimiento?

Author: curiousguy, 2009-09-21

30 answers

Esto no está relacionado con el rendimiento en absoluto. Pero considera esto: estás usando dos bibliotecas llamadas Foo y Bar:

using namespace foo;
using namespace bar;

Todo funciona bien, puedes llamar Blah() desde Foo y Quux() 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 llamada Quux(). Ahora tienes un conflicto: Tanto Foo 2.0 como Bar import Quux() en tu espacio de nombres global. Esto va a tomar un poco de esfuerzo para arreglar, especialmente si los parámetros de la función suceden a coincidir.

Si hubieras usado foo::Blah() y bar::Quux(), entonces la introducción de foo::Quux() habría sido un no-evento.

 1805
Author: Greg Hewgill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-14 16:37:43

Estoy de acuerdo con todo Greg escribió , pero me gustaría añadir: ¡Incluso puede ser peor de lo que dijo Greg!

La biblioteca Foo 2.0 podría introducir una función, Quux(), que es una coincidencia inequívocamente mejor para algunas de sus llamadas a Quux() que la bar::Quux() a la que su código llamó durante años. Entonces su el código aún compila, pero silenciosamente llama a la función incorrecta y dios sabe qué. Eso es tan malo como las cosas pueden conseguir.

Tenga en cuenta que el espacio de nombres std tiene toneladas de identificadores, muchos de los cuales son muy comunes (piense list, sort, string, iterator, etc.) que es muy probable que aparezcan en otro código, también.

Si consideras esto improbable: Hubo una pregunta hecha aquí en Stack Overflow donde casi exactamente sucedió esto (función incorrecta llamada debido al prefijo omitido std::) aproximadamente medio año después de que di esta respuesta. Aquí es otro, más ejemplo reciente de tal pregunta. Así que este es un verdadero problema.


Aquí hay un punto de datos más: Hace muchos, muchos años, también solía encontrar molesto tener que prefijar todo desde la biblioteca estándar con std::. Luego trabajé en un proyecto donde se decidió al principio que tanto las directivas using como las declaraciones están prohibidas, excepto para los ámbitos de función. ¿Adivina qué? A la mayoría de nosotros nos tomó muy pocas semanas acostumbrarnos a escribir el prefijo, y después de unas semanas más, la mayoría de nosotros incluso de acuerdo en que en realidad hizo el código más legible. Hay una razón para eso.: Si te gusta la prosa más corta o más larga es subjetivo, pero los prefijos objetivamente añadir claridad al código. No solo el compilador, sino que 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 (permitido) function-scope using en realidad se utilizó en el proyecto. Grep'd las fuentes para él y sólo encontró una o dos docenas de lugares donde se utilizó. Para mí, esto indica que, una vez probado, los desarrolladores no encuentran std:: lo suficientemente doloroso como para emplear directivas de uso, incluso una vez cada 100 kLoC, incluso cuando se permitió su uso.


En pocas palabras: Anteponer explícitamente todo no hace ningún daño, toma muy poco acostumbrarse y tiene ventajas objetivas. En particular, hace que el código más fácil de interpretar por el compilador y por los lectores humanos, y ese debería ser probablemente el objetivo principal al escribir código.

 1178
Author: sbi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-27 20:31:03

Creo que es malo ponerlo en los archivos de encabezado de sus clases: porque entonces estaría forzando a cualquiera que quiera usar sus clases (incluyendo sus archivos de encabezado) a también 'usar' (es decir, ver todo en) esos otros espacios de nombres.

Sin embargo, puede sentirse libre de poner una declaración de uso en su (privado) *.archivos cpp.


Tenga en cuenta que algunas personas no están de acuerdo con que diga "siéntase libre" de esta manera because porque aunque una declaración de uso 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 es bueno (porque dependiendo del código podría hacer que la implementación de la clase sea más difícil de mantener). Este tema de preguntas frecuentes dice,

La directiva using existe para el código C++ heredado y para facilitar la transición a los espacios de nombres, pero probablemente no debería usarla de forma regular, al menos no en su nuevo código C++.

Sugiere dos alternativas:

  • Una declaración de uso:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • Supéralo y simplemente escribe std::

    std::cout << "Values:";
    
 320
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-20 21:39:14

Recientemente me encontré con una queja sobre Visual Studio 2010 . Resultó que casi todos los archivos fuente tenían estas dos líneas:

using namespace std;
using namespace boost;

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 estaban compilando.

Por lo tanto, evitar using namespace X; es una forma de preparación para el futuro, una forma de asegurarse de que un cambio en las bibliotecas y / o archivos de encabezado en uso no va a romper un programa.

 204
Author: David Thornley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-11 10:33:18

Versión corta: no utilice global usando declaraciones o directivas en archivos de cabecera. Siéntase libre de usarlos en archivos de implementación. Esto es lo que Herb Sutter y Andrei Alexandrescu tienen que decir sobre este tema en C++ Coding Standards (negrita para el énfasis es mío):

Resumen

Los usos del espacio de nombres son para su conveniencia, no para que usted inflija a otros: Nunca escriba una declaración de uso o una directiva de uso antes de una directiva #include.

Corolario: En los archivos de cabecera, no escriba a nivel de espacio de nombres usando directivas o declaraciones; en su lugar, califica explícitamente a todos los nombres. (La segunda regla sigue a la primera, porque los encabezados nunca pueden saber qué otro encabezado # incluye podría aparecer después de ellos.)

Discusión

En resumen: Puede y debe usar el espacio de nombres usando declaraciones y directivas liberalmente en sus archivos de implementación después de #incluir directivas y sentirse bien al respecto. A pesar de aseveraciones repetidas de lo contrario, los espacios de nombres que usan declaraciones y directivas no son malos y no frustran el propósito de los espacios de nombres. Más bien, son los que hacen que los espacios de nombres sean utilizables.

 170
Author: mattnewport,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-03 20:00:25

No se debe usar la directiva using en el ámbito global, especialmente en las cabeceras. Sin embargo, hay situaciones en las que es apropiado incluso en un archivo de encabezado:

template <typename FloatType> inline
FloatType compute_something(FloatType x)
{
    using namespace std; //no problem since scope is limited
    return exp(x) * (sin(x) - cos(x * 2) + sin(x * 3) - cos(x * 4));
}

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 coma flotante definidos por el usuario (mediante Búsqueda Dependiente de Argumentos).

 107
Author: robson3.14,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-05 16:32:46

No lo use globalmente

Se considera "malo" solo cuando se usa globalmente. Porque:

  • Usted desordena el espacio de nombres en el que está programando.
  • Los lectores tendrán dificultades para ver de dónde viene un identificador en particular, cuando se utilizan muchos using namespace xyz.
  • Lo que es cierto para otros lectores de su código fuente es aún más cierto para el lector más frecuente de él: usted mismo. Volver en un año o dos y tomar una Mira...
  • Si solo hablas de using namespace std es posible que no seas consciente de todas las cosas que tomas -- y cuando añades otra #include o te mueves a una nueva revisión de C++ es posible que obtengas conflictos de nombres de los que no eras consciente.

Puede usarlo localmente

Sigue adelante y úsalo localmente (casi) libremente. Esto, por supuesto, le impide repetir std::} y la repetición también es mala.

Un modismo para usarlo localmente

En C++03 había un modismo idi boilerplate code for para implementar una función swap para sus clases. Se sugirió que en realidad se utiliza un local using namespace std} o al menos using std::swap:

class Thing {
    int    value_;
    Child  child_;
public:
    // ...
    friend void swap(Thing &a, Thing &b);
};
void swap(Thing &a, Thing &b) {
    using namespace std;      // make `std::swap` available
    // swap all members
    swap(a.value_, b.value_); // `std::stwap(int, int)`
    swap(a.child_, b.child_); // `swap(Child&,Child&)` or `std::swap(...)`
}

Esto hace la siguiente magia:

  • El compilador elegirá el std::swap para value_, es decir, void std::swap(int, int).
  • Si tiene una sobrecarga void swap(Child&, Child&) implementada, el compilador la elegirá.
  • Si no tiene esa sobrecarga el compilador usará void std::swap(Child&,Child&) e intentará su mejor intercambio de estos.

Con C++11 ya no hay razón para usar este patrón. La implementación de std::swap se cambió para encontrar una sobrecarga potencial y elegirla.

 83
Author: towi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 07:35:50

Si importa el derecho archivos de encabezado de repente tienen nombres como hex, left, plus o count en el ámbito global. Esto podría ser sorprendente si usted no es consciente de que std:: contiene estos nombres. Si también intenta usar estos nombres localmente puede llevar a 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.

 71
Author: sth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-31 22:17:41

Los programadores experimentados usan lo que resuelve sus problemas y evitan lo que crea nuevos problemas, y evitan las directivas de uso a nivel de archivo de encabezado por esta misma razón.

Los programadores experimentados también tratan de 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? A veces los programadores explícitamente quieren desactivar ADL, otras veces quieren desambiguar.

Así que lo siguiente está bien:

  1. Directivas y declaraciones de uso a nivel de función dentro de las implementaciones de funciones
  2. Source-file-level using-declarations inside source files
  3. (A veces) a nivel de archivo-fuente usando-directivas
 36
Author: Alexander Poluektov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 20:53:41

Estoy de acuerdo en que no debe usarse globalmente, pero no es tan malo usarlo localmente, como en un namespace. Aquí hay un ejemplo de " El Lenguaje de programación C++ " :

namespace My_lib {

    using namespace His_lib; // everything from His_lib
    using namespace Her_lib; // everything from Her_lib

    using His_lib::String; // resolve potential clash in favor of His_lib
    using Her_lib::Vector; // resolve potential clash in favor of Her_lib

}

En este ejemplo, resolvimos posibles conflictos de nombres y ambigüedades que surgen de su composición.

Los nombres explícitamente declarados allí (incluidos los nombres declarados mediante declaraciones de uso como His_lib::String) tienen prioridad sobre los nombres accesibles en otro ámbito por una directiva de uso (using namespace Her_lib).

 34
Author: Oleksiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-29 09:44:39

Otra razón es la sorpresa.

Si veo cout << blah en lugar de std::cout << blah

Creo que ¿qué es esto cout? ¿Es lo normal cout? Es algo especial?

 33
Author: Martin Beckett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-29 12:40:46

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 las cosas, así que no debería estropearlo arrojando todo en una bolsa global. Sin embargo, si uso a menudo '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 nombrará jamás una corriente cout o cin. ;)

 23
Author: Yelonek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-21 09:34:19

Es bueno ver código y saber lo que hace. Si veo std::cout sé que es el flujo cout de la biblioteca std. Si veo cout entonces no lo sé. podría ser el flujo cout de la biblioteca std. O podría haber un int cout = 0; diez líneas más arriba en la misma función. O una variable static llamada cout en ese archivo. Podría ser cualquier cosa.

Ahora toma una base de código de millones de líneas, que no es particularmente grande, y estás buscando un error, lo que significa que sabes que hay uno línea en este millón de líneas que no hace lo que se supone que debe hacer. cout << 1; podría leer un static int llamado cout, desplazarlo a la izquierda por un bit, y tirar el resultado. Buscando un micrófono, tendría que comprobarlo. ¿Puedes ver cómo realmente prefiero ver std::cout?

Es una de estas cosas que parece una muy buena idea si eres profesor y nunca has tenido 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 el la persona que lo escribía sabía lo que hacía.

 19
Author: gnasher729,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-29 12:47:01

Se trata de gestionar la complejidad. El uso del espacio de nombres atraerá cosas que no desea, y por lo tanto posiblemente haga que sea más difícil depurar (digo posiblemente). Usar std:: en todo el lugar es más difícil de leer (más texto y todo eso).

Horses for courses - gestionar su complejidad de la mejor manera que puede y se siente capaz.

 18
Author: Preet Sangha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-25 19:40:31
  1. Necesitas ser capaz de leer código escrito por personas que tienen diferentes opiniones de estilo y mejores prácticas que tú.

  2. Si solo estás usando cout, nadie se confunde. Pero cuando tienes muchos espacios de nombres volando y ves esta clase y no estás exactamente seguro de lo que hace, tener el espacio de nombres explícito actúa como un comentario de clases. Se puede ver a primera vista, 'oh, esta es una operación de sistema de archivos' o 'eso está haciendo cosas de red'.

 15
Author: Dustin Getz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-21 04:16:31

Usar muchos espacios de nombres al mismo tiempo es obviamente una receta para el desastre, pero usar solo espacio de nombres std y solo espacio de nombres std no es tan importante en mi opinión porque la redefinición solo puede ocurrir por su propio código...

Así que considéralas funciones como nombres reservados como "int" o "class" y eso es todo.

Las personas deberían dejar de ser tan anales al respecto. Tu profesor tenía razón todo el tiempo. Simplemente use UN espacio de nombres; ese es el punto de usar espacios de nombres primer lugar. Se supone que no debe usar más de uno al mismo tiempo. A menos que sea tuyo. Así que de nuevo, la redefinición no sucederá.

 15
Author: user2645752,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-11 10:44:02

Considere

// myHeader.h
#include <sstream>
using namespace std;


// someoneElses.cpp/h
#include "myHeader.h"

class stringstream {  // uh oh
};

Tenga en cuenta que este es un ejemplo simple, si tiene archivos con 20 includes y otras importaciones, tendrá un montón de dependencias que revisar para resolver el problema. Lo peor de esto es que puede obtener errores no relacionados en otros módulos dependiendo de las definiciones que entran en conflicto.

No es horrible, pero te ahorrarás 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 un problema escribiendo los 5 caracteres adicionales para aclarar de dónde vienen mis funciones.

 14
Author: Ron Warholic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-16 09:53:04

Un espacio de nombres es un ámbito con nombre. Los espacios de nombres se utilizan para agrupar declaraciones relacionadas y para mantener separadas artículos separados. 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:

namespace Mylib{
    template<class T> class Stack{ /* ... */ };
    / / ...
}
namespace Yourlib{
    class Stack{ /* ... */ };
    / / ...
}
void f(int max) {
    Mylib: :Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

Repetir un nombre de espacio de nombres puede ser una distracción tanto para lectores como para escritores. En consecuencia, es posible para indicar que los nombres de un espacio de nombres en particular están disponibles sin calificación explícita. Para ejemplo:

void f(int max) {
    using namespace Mylib; / / make names from Mylib accessible
    Stack<int> s1(max) ; / / use my stack
    Yourlib: :Stack s2(max) ; / / use your stack
    / / ...
}

Los espacios de nombres proporcionan una poderosa herramienta para la gestión de diferentes bibliotecas y de diferentes versiones de codificar. En particular, ofrecen al programador alternativas de cómo explicitar hacer una referencia a un no local nombre.

Fuente: Una visión general del Lenguaje de programación C++ de Bjarne Stroustrup

 10
Author: Rohan Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-09 22:26:54

Un ejemplo concreto para aclarar la preocupación. Imagine que tiene una situación en la que tiene 2 bibliotecas, foo y bar, cada una con su propio espacio de nombres:

namespace foo {
    void a(float) { /* does something */ }
}

namespace bar {
    ...
}

Ahora digamos que usas foo y bar juntos en tu propio programa de la siguiente manera:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

En este punto, todo está bien. Cuando ejecuta su programa 'hace algo'. Pero más tarde actualizas la barra y digamos que ha cambiado para ser como:

namespace bar {
    void a(float) { /* does something completely different */ }
}

En este punto obtendrás un compilador error:

using namespace foo;
using namespace bar;

void main() {
    a(42);  // error: call to 'a' is ambiguous, should be foo::a(42)
}

Así que tendrás que hacer algún mantenimiento para aclarar qué 'a' querías decir (es decir, foo::a). Eso es probablemente indeseable, pero afortunadamente es bastante fácil (simplemente agregue foo:: delante de todas las llamadas a a que el compilador marca como ambiguas).

Pero imagine un escenario alternativo donde bar cambió para verse así: {[12]]}

namespace bar {
    void a(int) { /* does something completely different */ }
}

En este punto, su llamada a a(42) de repente se une a bar::a en lugar de foo::a y en lugar de hacer 'algo' lo hace "algo completamente diferente". No hay advertencia de compilador ni nada. Su programa simplemente en silencio comienza a hacer algo completamente diferente que antes.

Cuando usas un espacio de nombres estás arriesgando un escenario como este, por lo que la gente se siente incómoda usando espacios de nombres. Cuantas más cosas haya en un espacio de nombres, mayor será el riesgo de conflicto, por lo que las personas podrían sentirse aún más incómodas usando namespace std (debido al número de cosas en ese espacio de nombres) que otras espacios de nombres.

En última instancia, esto es una compensación entre escritura vs confiabilidad/mantenibilidad. La legibilidad también puede tener en cuenta, pero podría ver argumentos para eso en cualquier sentido. Normalmente diría que la confiabilidad y la capacidad de mantenimiento son más importantes, pero en este caso pagará constantemente el costo de escritura por un impacto de confiabilidad/capacidad de mantenimiento bastante raro. La' mejor ' compensación determinará su proyecto y sus prioridades.

 10
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-02 14:35:55

Un ejemplo donde el uso de std de espacio de nombres arroja un error de complilación debido a la ambigüedad de count, que también es una función en la biblioteca de algoritmos.

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout<<count<<endl;
}
 8
Author: Nithin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-31 08:00:36

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 declaración de archivo, función o clase.

Normalmente 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 es significativo en el contexto de la clase. Esto realmente ayuda a la legibilidad en las definiciones de la clase método.

//header
class File
{
   typedef std::vector<std::string> Lines;
   Lines ReadLines();
}

Y en la implementación:

//cpp
Lines File::ReadLines()
{
    Lines lines;
    //get them...
    return lines;
}

A diferencia de:

//cpp
vector<string> File::ReadLines()
{
    vector<string> lines;
    //get them...
    return lines;
}

O:

//cpp
std::vector<std::string> File::ReadLines()
{
    std::vector<std::string> lines;
    //get them...
    return lines;
}
 8
Author: Carl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 00:40:14

"¿Por qué 'usar el espacio de nombres std;' se considera una mala práctica en C++?"

Lo pongo al revés: ¿Por qué escribir 5 caracteres adicionales es considerado engorroso por algunos?

Considere, por ejemplo, escribir una pieza de software numérico, ¿por qué consideraría incluso contaminar mi espacio de nombres global al cortar "std::vector" general a "vector" cuando "vector" es uno de los conceptos más importantes del dominio del problema?

 6
Author: Solkar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-13 15:18:27

No creo que sea necesariamente una mala práctica en todas las condiciones, pero debe tener cuidado cuando lo use. Si está escribiendo una biblioteca, probablemente debería usar los operadores de resolución de ámbito con el espacio de nombres para evitar que su biblioteca se entrometa con otras bibliotecas. Para el código de nivel de aplicación, no veo nada malo en él.

 5
Author: Dr. Watson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-21 03:34:06

Para responder a tu pregunta lo veo de esta manera prácticamente: muchos programadores (no todos) invocan namespace std. Por lo tanto, uno debe tener el hábito de NO usar cosas que afecten o usen los mismos nombres que lo que está en el espacio de nombres std. Se trata de un gran acuerdo, pero no tanto en comparación con el número de posibles palabras y seudónimos coherentes que se pueden inventar estrictamente hablando.

Quiero decir realmente... decir "no confíes en que esto esté presente" es solo prepararte para confía en que no esté presente. Constantemente va a tener problemas tomando prestados fragmentos de código y constantemente reparándolos. Simplemente mantenga sus cosas prestadas y definidas por el usuario en un alcance limitado como deberían ser y sea MUY respetuoso con las globales (honestamente, las globales casi siempre deben ser un último recurso para propósitos de "compilar ahora, cordura más tarde"). Realmente creo que es un mal consejo de su maestro porque usar ets funcionará tanto para "cout"como" std:: cout", pero NO usar ets solo funcionará para "std::cout". No siempre tendrás la suerte de escribir todo tu propio código.

NOTA: No se centre demasiado en los problemas de eficiencia hasta que realmente aprenda un poco sobre cómo funcionan los compiladores. Con un poco de experiencia en 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 lo escribieras todo en C. El buen código es tan complejo como debe ser.

 4
Author: Noneyo Getit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-27 20:33:03

Según mis experiencias, si tienes varias bibliotecas que usan, por ejemplo, cout, pero para un propósito diferente puedes usar el cout incorrecto.

Por ejemplo, si escribo, using namespace std; y using namespace otherlib; y escribo solo cout (que sucede que está en ambos), en lugar de std::cout (o 'otherlib::cout'), puede usar el incorrecto y obtener errores, es mucho más efectivo y eficiente usar std::cout.

 4
Author: Engine Dev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-21 02:11:40

Esta es una mala práctica, a menudo conocida como contaminación del espacio de nombres global. Los problemas pueden ocurrir cuando más de un espacio de nombres tiene el mismo nombre de función con firma, entonces será ambiguo para el compilador decidir a cuál llamar y todo esto se puede evitar cuando se especifica el espacio de nombres con la llamada a la función como std::cout . Espero que esto ayude. :)

 4
Author: adn.911,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 16:24:48

Estoy de acuerdo con los demás – se está pidiendo enfrentamientos de nombres, ambigüedades y luego 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 algunos 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 espacio de nombres std (o al revés: desea cambiar todas las llamadas que NO están en el espacio de nombres std, el espacio de nombres X,...), entonces cómo ¿te propones hacer esto? Podría escribir un programa para hacerlo, pero ¿no sería mejor pasar tiempo trabajando en su proyecto en lugar de escribir un programa para mantener su proyecto?

Personalmente no me importa el prefijo std::. Me gusta el look más que no tenerlo. No se 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 yo recientemente me metí en C++ (uso y todavía uso C y otros lenguajes por mucho más tiempo y C es mi lenguaje favorito de todos los tiempos, justo por encima del ensamblado).

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 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 empecé este proyecto desde cero y soy el único programador para ello. Ejemplo: Sobrecarga std::string y lo llamo string. Tengo adiciones útiles. Lo hice en parte debido a mi tendencia de C y Unix (+Linux) hacia 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. Utilizo el estándar C++11 y específicamente con libstdc++. Bueno, no tiene soporte completo std::regex. Seguro que compila pero lanza una excepción las líneas de que es un error en el extremo del programador. Pero es falta de implementación. Así que así es como lo resolví. Instala la expresión regular de Boost, enlázala. Luego, hago lo siguiente para que cuando libstdc++ lo haya implementado por completo, solo tenga que eliminar este bloque y el código siga siendo el mismo:

namespace std
{
    using boost::regex;
    using boost::regex_error;
    using boost::regex_replace;
    using boost::regex_search;
    using boost::regex_match;
    using boost::smatch;
    namespace regex_constants = boost::regex_constants;  
}

No voy a discutir si eso 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 que tengo que usar Boost PERO estoy usándolo como el libstdc++ eventualmente lo tendrá. Sí, comenzar su propio proyecto y comenzar con un estándar (...) al principio va un largo camino con ayudar al mantenimiento, desarrollo y todo lo relacionado con el proyecto!

Editar:
Ahora que tengo tiempo, sólo para aclarar algo. En realidad no creo que sea una buena idea usar un 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 (ignorar el primero, arriba, o el segundo aquí, juego de palabras si es necesario) para mí, ya que no me gustó la idea de 'Cadena'. Como es, todavía estoy muy sesgado hacia C y sesgado contra C++. Ahorrando detalles, mucho de lo que trabajo en ajustes C más (pero fue un buen ejercicio y una buena manera de hacerme a. aprender otro idioma y b. tratar de no ser menos sesgado contra el objeto/clases/etc que es tal vez mejor declarado como menos cerrado de mente, menos arrogante, más aceptar.). Pero lo que es útil es lo que algunos ya han sugerido: de hecho usar lista (es bastante genérico, ¿no es así ?), ordenar (lo mismo) para nombrar dos que causarían un choque de nombres si tuviera que hacer using namespace std; y así para ese fin prefiero ser específico, en control y sabiendo que si tengo la intención de que sea el uso estándar, entonces tendré que especificarlo. En pocas palabras: no se permite asumir.

Y en cuanto a hacer que la expresión regular de Boost forme parte de std. Lo hago para la integración futura y – una vez más, admito plenamente que esto es sesgo - No creo que sea tan feo como boost::regex:: ... De hecho que es otra cosa para mí. Hay muchas cosas en C++ que todavía tengo que aceptar completamente en looks y métodos (otro ejemplo: plantillas variadic versus var args [aunque admito que las plantillas variadic son muy, muy útiles!]). Incluso aquellos que acepto fue difícil Y todavía tengo problemas con ellos.

 4
Author: tambre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-22 13:39:21

No empeora el rendimiento de su software o proyecto, la inclusión del espacio de nombres al principio de su código fuente no es mala. La inclusión de la instrucción using namespace std varía según sus necesidades y la forma en que está desarrollando el software o proyecto.

El namespace std contiene las funciones y variables estándar de C++. Este espacio de nombres es útil cuando se utilizan a menudo las funciones estándar de C++.

Como se menciona en esta página :

La instrucción que usa namespace std generalmente se considera mala practicar. La alternativa a esta declaración es especificar la espacio de nombres al que pertenece el identificador mediante el operador de ámbito(::) cada vez declaramos un tipo.

Y ver esta opinión:

No hay problema al usar "using namespace std" en su archivo fuente cuando hace un uso intensivo del espacio de nombres y sabe con certeza que nada chocará.

Algunas personas habían dicho es una mala práctica incluir el using namespace std en sus archivos fuente porque está invocando desde ese espacio de nombres todas las funciones y variables. Cuando se desea definir una nueva función con el mismo nombre que otra función contenida en el namespace std se sobrecargaría la función y podría producir problemas debido a la compilación o ejecución. No compilará ni ejecutará como esperas.

Como se menciona en esta página :

Aunque la declaración nos salva de escribir std:: siempre queremos acceder a una clase o tipo definido en el espacio de nombres std, importa la totalidad del espacio de nombres std en el espacio de nombres actual del programa. Tomemos algunos ejemplos para entender por qué esto podría no ser una cosa tan buena

...

Ahora, en una etapa posterior de desarrollo, deseamos usar otra versión de cout que se implementa a medida en alguna biblioteca llamada " foo " (para ejemplo)

...

Observe cómo hay ¿es una ambigüedad, a qué biblioteca apunta cout? El compilador puede detectar esto y no compilar el programa. En el peor caso, el programa todavía puede compilar pero llamar a la función incorrecta, ya que nunca especificamos a qué espacio de nombres pertenecía el identificador.

 4
Author: CryogenicNeo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-22 14:35:44

Con identificadores importados no calificados, necesita herramientas de búsqueda externas como grep para averiguar dónde se declaran los identificadores. Esto hace que el razonamiento sobre la corrección del programa sea más difícil.

 3
Author: August Karlstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-11 14:22:33

Depende de dónde se encuentre. Si es un encabezado común, entonces está disminuyendo el valor del espacio de nombres fusionándolo en el espacio de nombres global. Tenga en cuenta que esta podría ser una forma ordenada de hacer globales de módulos.

 3
Author: MathGladiator,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-11 10:18:06