Uso del espacio de nombres estándar

110

Parece haber diferentes puntos de vista sobre el uso de 'usar' con respecto al espacio de nombres estándar.

Algunos dicen usar ' using namespace std', otros dicen que no, sino prefijar las funciones estándar que se usarán con ' std::', mientras que otros dicen que use algo como esto:

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;

para todas las funciones estándar que se van a utilizar.

¿Cuáles son los pros y los contras de cada uno?

paoloricardo
fuente

Respuestas:

131

La mayoría de los usuarios de C ++ están muy contentos de leer std::string, std::vectoretc. De hecho, ver un archivo sin vectorformato me hace preguntarme si este es el std::vectordefinido por el usuario o uno diferente vector.

Siempre estoy en contra de consumir using namespace std;. Importa todo tipo de nombres en el espacio de nombres global y puede causar todo tipo de ambigüedades no obvias.

A continuación, se muestran algunos identificadores comunes que se encuentran en el stdespacio de nombres: contar, ordenar, buscar, igualar, invertir. Tener una variable local llamada countsignifica que using namespace stdno le permitirá usar en countlugar de std::count.

El ejemplo clásico de un conflicto de nombres no deseado es algo como el siguiente. Imagina que eres un principiante y no sabes nada std::count. Imagina que estás usando algo más <algorithm>o ha sido introducido por un encabezado aparentemente no relacionado.

#include <algorithm>
using namespace std;

int count = 0;

int increment()
{
    return ++count; // error, identifier count is ambiguous
}

El error suele ser largo y poco amigable porque std::countes una plantilla con algunos tipos anidados largos.

Sin embargo, esto está bien, porque std::countentra en el espacio de nombres global y el recuento de funciones lo oculta.

#include <algorithm>
using namespace std;

int increment()
{
    static int count = 0;
    return ++count;
}

Quizás sorprendentemente, esto está bien. Los identificadores importados en un ámbito declarativo aparecen en el espacio de nombres común que incluye tanto dónde se definen como dónde se importan. En otras palabras, std::countes visible como counten el espacio de nombres global, pero solo dentro increment.

#include <algorithm>

int increment()
{
    using namespace std;
    static int count = 0;
    return ++count;
}

Y por razones similares, countaquí es ambiguo. using namespace stdno causa std::count, esconde el exterior countcomo podría esperarse. La using namespaceregla significa que std::countparece (en la incrementfunción) como si estuviera declarada en el ámbito global, es decir, en el mismo ámbito int count = 0;y, por tanto, provocando la ambigüedad.

#include <algorithm>

int count = 0;

int increment()
{
    using namespace std;
    return ++count; // error ambiguous
}
CB Bailey
fuente
21
pero vale tipos taaaan mucho más fácil sin el prefijo std ::!
xtofl
69
@xtofl: No, no es así. Cinco caracteres no son tan relevantes al escribir, pero estos cinco caracteres pueden ser muy relevantes al leer. Y la facilidad de lectura cuenta mucho más que la facilidad de escribir el código fuente, ya que el código es mucho más leído que escrito.
sbi
3
Podría agregar que la declaración using se comporta correctamente con las reglas de alcance.
Martin York
2
@Martin York: actualizado con ejemplos que ilustran las reglas de alcance. @Michael Burr: Podría decirse que eso no es tan malo, lo que realmente no me gusta es dónde los mensajes de error por errores simples se vuelven mucho más difíciles de interpretar, o dónde no ocurren en absoluto. Por ejemplo, si se cree que una función está dentro del alcance, pero no lo está y una función std :: lo está, en lugar de obtener un útil error de 'identificador no reconocido', a menudo terminas con un argumento más oscuro de 'no se puede convertir Error de estilo X 'o' no se puede generar la función a partir de la plantilla '. Lo peor es si se llama silenciosamente a una función incorrecta. Es raro, pero sucede.
CB Bailey
5
Bueno, me sorprende que nadie haya hablado de la opción de using std::xxx;. No contamina el espacio de nombres, la escritura del código será más corta y creo que copyes mucho más real que std::copy.
legends2k
41

Excluyendo los conceptos básicos (tener que agregar std :: enfrente de todos los objetos / funciones stl y menos posibilidades de conflicto si no tiene 'using namespace std')

También vale la pena señalar que nunca debe poner

using namespace std

En un archivo de encabezado, ya que puede propagarse a todos los archivos que incluyen ese archivo de encabezado, incluso si no quieren usar ese espacio de nombres.

En algunos casos, es muy beneficioso usar cosas como

using std::swap

Como si hubiera una versión especializada de swap, el compilador la usará, de lo contrario recurrirá a ella std::swap.

Si llama std::swap, siempre usa la versión básica, que no llamará a la versión optimizada (si existe).

Yacoby
fuente
10
+1 por mencionar using std::swap(que es lo único que uso).
sbi
1
+1 por mencionar que se u n spuede propagar. Solo para tener en cuenta que también puede abrirse camino en encabezados construidos correctamente: solo deben incluirse después de un encabezado falso.
quamrana
1
Pero si está definiendo una especialización swapo move(o hash, lessetc.), debería poner esa especialización de namespace stdtodos modos. Por ejemplo:namespace std {template<> class hash<X> {public: size_t operator()(const X&) const};} class X: {friend size_t std::hash<X>::operator()(const X&)};
AJMansfield
28

Primero, algo de terminología:

  • declaración de uso : using std::vector;
  • directiva-de-uso : using namespace std;

Creo que el uso de directivas de uso está bien, siempre que no se utilicen en el ámbito global en un archivo de encabezado. Así que teniendo

using namespace std;

en su archivo .cpp no ​​es realmente un problema, y ​​si resulta serlo, está completamente bajo su control (e incluso puede tener un alcance en bloques particulares si lo desea). No veo ninguna razón en particular para saturar el código con una gran cantidad de std::calificadores, simplemente se convierte en un montón de ruido visual. Sin embargo, si no está usando un montón de nombres del stdespacio de nombres en su código, tampoco veo ningún problema en omitir la directiva. Es una tautología: si la directiva no es necesaria, no es necesario utilizarla.

De manera similar, si puede arreglárselas con algunas declaraciones de uso (en lugar de directivas de uso ) para tipos específicos en el stdespacio de nombres, entonces no hay razón por la que no deba traer solo esos nombres específicos al espacio de nombres actual. De la misma manera, creo que sería una locura y una molestia contable tener 25 o 30 declaraciones de uso cuando una sola directiva de uso funcionaría igual de bien.

También es bueno tener en cuenta que hay ocasiones en las que debe usar una declaración using. Consulte el "Elemento 25: Considere la posibilidad de admitir un intercambio sin lanzamiento" de Scott Meyers de Effective C ++, tercera edición. Para que una función genérica con plantilla use el 'mejor' método de intercambio para un tipo parametrizado, debe hacer uso de una declaración de uso y una búsqueda dependiente de argumentos (también conocida como búsqueda de ADL o Koenig):

template< typename T >
void foo( T& x, T& y)
{
    using std::swap;     // makes std::swap available in this function

    // do stuff...

    swap( x, y);         // will use a T-specific swap() if it exists,
                         //  otherwise will use std::swap<T>()

    // ...
 }

Creo que deberíamos mirar los modismos comunes para varios idiomas que hacen un uso significativo de los espacios de nombres. Por ejemplo, Java y C # usan espacios de nombres en gran medida (posiblemente más que C ++). La forma más común en que los nombres dentro de los espacios de nombres se usan en esos lenguajes es llevándolos al alcance actual en masa con el equivalente de una directiva using. Esto no causa problemas generalizados, y las pocas veces que se trata de un problema se maneja en forma de "excepción" tratando con los nombres en cuestión a través de nombres completamente calificados o mediante alias, como se puede hacer en C ++.

Herb Sutter y Andrei Alexandrescu tienen esto que decir en "Ítem 59: No escriba usos de espacios de nombres en un archivo de encabezado o antes de un #include" de su libro, Estándares de codificación C ++: 101 reglas, pautas y mejores prácticas:

En resumen: puede y debe usar el espacio de nombres usando declaraciones y directivas libremente en sus archivos de implementación después #include directivas y sentirse bien al respecto. A pesar de las repetidas afirmaciones en sentido contrario, los espacios de nombres que utilizan 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.

Stroupstrup a menudo se cita diciendo, "No contaminen el espacio de nombres global", en "El lenguaje de programación C ++, tercera edición". De hecho dice eso (C.14 [15]), pero se refiere al capítulo C.10.1 donde dice:

Una declaración de uso agrega un nombre a un ámbito local. Una directiva de uso no lo hace; simplemente hace que los nombres sean accesibles en el ámbito en el que fueron declarados. Por ejemplo:

namespaceX {
    int i , j , k ;
}

int k ;
void f1()
{
    int i = 0 ;

    using namespaceX ; // make names from X accessible

    i++; // local i
    j++; // X::j
    k++; // error: X::k or global k ?

    ::k ++; // the global k

    X::k ++; // X’s k
}

void f2()
{
    int i = 0 ;

    using X::i ; // error: i declared twice in f2()
    using X::j ;
    using X::k ; // hides global k

    i++;
    j++; // X::j
    k++; // X::k
}

Un nombre declarado localmente (declarado por una declaración ordinaria o por una declaración de uso) oculta declaraciones no locales del mismo nombre, y cualquier sobrecarga ilegal del nombre se detecta en el punto de declaración.

Tenga en cuenta el error de ambigüedad para k++en f1() . Los nombres globales no tienen preferencia sobre los nombres de los espacios de nombres accesibles en el ámbito global. Esto proporciona una protección significativa contra conflictos de nombres accidentales y, lo que es más importante, garantiza que no se obtengan ventajas al contaminar el espacio de nombres global.

Cuando las bibliotecas que declaran muchos nombres se hacen accesibles a través de directivas de uso, es una ventaja significativa que los conflictos de nombres no utilizados no se consideren errores.

...

Espero ver una disminución radical en el uso de nombres globales en nuevos programas que utilizan espacios de nombres en comparación con los programas tradicionales de C y C ++. Las reglas para los espacios de nombres se diseñaron específicamente para no ofrecer ventajas a un usuario "perezoso" de nombres globales sobre alguien que se cuida de no contaminar el alcance global.

¿Y cómo se tiene la misma ventaja que un 'usuario perezoso de nombres globales'? Aprovechando la directiva using, que hace que los nombres de un espacio de nombres estén disponibles para el ámbito actual de forma segura .

Tenga en cuenta que hay una distinción: los nombres en el stdespacio de nombres puestos a disposición de un ámbito con el uso adecuado de una directiva de uso (colocando la directiva después de #includes) no contaminan el espacio de nombres global. Es simplemente hacer que esos nombres estén disponibles fácilmente y con una protección continua contra los enfrentamientos.

Michael Burr
fuente
Con respecto a su último punto: Java y C # también tienen espacios de nombres mucho más prolijos. Si todo en el BCL viviera en System, "usar System" causaría tantos problemas como "usar namespace std".
Jeff Hardy
Pero los programas Java y C # que veo normalmente incluyen todos los espacios de nombres que usan, no solo "Sistema" (o su equivalente). Entonces, en lugar de una única directiva using que incluya todos los nombres usados, hay 5 o 10 que hacen más o menos lo mismo. Además, "using namespace std;" realmente causa tantos problemas?
Michael Burr
El problema es que std tiene demasiados nombres comunes y que incluir un encabezado estándar puede incluir todos los demás. No tenemos un buen control sobre lo que se importa, hay demasiados riesgos. No sé lo suficiente sobre Java y C #, pero sé sobre Ada, que tiene un sistema de módulos mucho mejor que C ++ y donde la importación de nombres generalmente está mal vista. En general, es primero una cuestión de convención de nomenclatura (he visto personas que usan prefijos y espacios de nombres, no importar no tiene sentido) y luego de estilo.
Programador
1
Todavía no estoy convencido de que este sea un problema del mundo real. Veo que las directivas de uso se utilizan todo el tiempo sin graves inconvenientes. Por otra parte, no tengo ningún problema en no usarlos. Simplemente prefiero que los std::calificadores no abarroten el código; hay otras formas de evitar eso (las declaraciones de uso o las definiciones de tipo suelen hacer el truco).
Michael Burr
1
@AProgrammer: dices, "la lista es un identificador natural para identificar la lista en un intérprete lisp", pero tener la using namespace std;directiva " " no te impide declarar tu identificador natural list", es solo que si lo haces, no puedes uso más prolongado std::listsin calificarlo. Eso no es diferente a si no hay " using namespace std;" directiva. ¿O me estoy perdiendo algo?
Michael Burr
17

Nunca use el uso del espacio de nombres en el ámbito global en un archivo de encabezado. Eso puede dar lugar a un conflicto y la persona a cargo del archivo donde aparece el conflicto no tiene control sobre la causa.

En el archivo de implementación, las opciones están mucho peor cortadas.

  • Poner un espacio de nombres using std trae todos los símbolos de esos espacios de nombres. Esto puede ser problemático ya que casi nadie conoce todos los símbolos que están allí (por lo que es imposible aplicar una política de no conflicto en la práctica) sin hablar de los símbolos que se agregarán. Y el estándar C ++ permite que un encabezado agregue símbolos de otros encabezados (el C no permite eso). Todavía puede funcionar bien en la práctica para simplificar la escritura en caso controlado. Y si ocurre un error, se detecta en el archivo que tiene el problema.

  • Poner usando std :: nombre; tiene la ventaja de la sencillez de escritura sin el riesgo de importar símbolos desconocidos. El costo es que debe importar explícitamente todos los símbolos deseados.

  • La calificación explícita agrega un poco de desorden, pero creo que es la práctica menos problemática.

En mi proyecto, uso una calificación explícita para todos los nombres, acepto usar std :: name, lucho contra usar el espacio de nombres std (tenemos un intérprete lisp que tiene su propio tipo de lista y, por lo tanto, el conflicto es algo seguro).

Para otros espacios de nombres, también debe tener en cuenta las convenciones de nomenclatura utilizadas. Sé de un proyecto que usa espacio de nombres (para control de versiones) y prefijo en nombres. Hacer un using namespace Xthen es casi sin riesgo y no hacerlo conduce a un código de aspecto estúpidoPrefixNS::pfxMyFunction(...) .

Hay algunos casos en los que desea importar los símbolos. std :: swap es el caso más común: importa std :: swap y luego usa swap unqualified. La búsqueda dependiente del argumento encontrará un intercambio adecuado en el espacio de nombres del tipo, si hay uno, y volverá a la plantilla estándar si no hay ninguno.


Editar:

En los comentarios, Michael Burr se pregunta si los conflictos ocurren en el mundo real. Aquí hay un ejemplo real en vivo. Tenemos un idioma de extensión con un dialecto ceceo. Nuestro intérprete tiene un archivo de inclusión, lisp.h que contiene

typedef struct list {} list;

Tuvimos que integrar y adaptar un código (que llamaré "motor") que se veía así:

#include <list>
...
using std::list;
...
void foo(list const&) {}

Así que modificamos así:

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

Bueno. Todo funciona. Algunos meses más tarde, "module.h" fue modificado para incluir "list.h". Pasaron las pruebas. "módulo" no se había modificado de una manera que afectara su ABI, por lo que la biblioteca "motor" podría usarse sin volver a compilar sus usuarios. Las pruebas de integración estuvieron bien. Nuevo "módulo" publicado. La siguiente compilación del motor se rompió cuando su código no se ha modificado.

Un programador
fuente
1
Uno de los casos controlados en los que creo que el uso del espacio de nombres es aceptable es en la publicación de código. La simplificación facilita el diseño de la página y ayuda a concentrarse en el punto expuesto. El inconveniente es que realmente no muestra una buena práctica, por lo que no lo usaría en libros para principiantes.
Programador
1
Creo que escribir std :: es un pequeño precio a pagar por la claridad
paoloricardo
4
@paoloricardo: Por otro lado, creo que tener std :: apareciendo por todas partes es un desorden visual innecesario.
Michael Burr
1
@Michael: ¡pagas tu dinero y haces tu elección!
paoloricardo
2
Gracias por tomarse el tiempo para agregar los detalles del problema con el que se encontró.
Michael Burr
4

Si no tiene riesgo de conflictos de nombres en su código con std y otras bibliotecas, puede usar:

using namespace std;

Pero si desea saber con precisión la dependencia de su código para la documentación o existe el riesgo de conflictos de nombres, utilice el otro método:

using std::string;
using std::cout;

La tercera solución, no use estas soluciones y escriba std :: antes de cada uso en el código le brinda más seguridad, pero tal vez un poco de peso en el código ...

Matthieu
fuente
4

Ambos

using std::string;

y

using namespace std;

agregue algunos símbolos (uno o muchos) al espacio de nombres global. Y agregar símbolos al espacio de nombres global es algo que nunca debe hacer en los archivos de encabezado. No tienes control sobre quién incluirá tu encabezado, hay muchos encabezados que incluyen otros encabezados (y encabezados que incluyen encabezados que incluyen encabezados, etc.).

En los archivos de implementación (.cpp), depende de usted (solo recuerde hacerlo después de todas las directivas #include). Puede romper solo el código en este archivo específico, por lo que es más fácil de administrar y descubrir el motivo del conflicto de nombres. Si prefiere usar std :: (o cualquier otro prefijo, puede haber muchos espacios de nombres en su proyecto) antes de los identificadores, está bien. Si desea agregar identificadores que usa al espacio de nombres global, está bien. Si desea traer todo el espacio de nombres en su cabeza :-), depende de usted. Si bien los efectos se limitan a una sola unidad de compilación, es aceptable.

Tadeusz Kopec
fuente
3

Para mí, prefiero usar ::cuando sea posible.

std::list<int> iList;

Odio escribir:

for(std::list<int>::iterator i = iList.begin(); i != iList.end(); i++)
{
    //
}

Con suerte, con C ++ 0x escribiría esto:

for(auto i = iList.begin(); i != iList.end(); i++)
{
    //
}

Si el espacio de nombres es muy extenso,

namespace dir = boost::filesystem;

dir::directory_iterator file("e:/boost");
dir::directory_iterator end;

for( ; file != end; file++)
{
    if(dir::is_directory(*file))
        std::cout << *file << std::endl;
}
AraK
fuente
@AraK: espacio de nombres dir = boost :: filesystem; ¿Supongo que es un alias?
paoloricardo
@paoloricardo: Sí, eso es lo que es.
sbi
2
Los iteradores deben incrementarse con ++i, no i++porque, si está definido, cree una copia temporal innecesaria del iterador.
Felix Dombek
2

Nunca debe estar using namespace stden el ámbito del espacio de nombres en un encabezado. Además, supongo que la mayoría de los programadores se preguntarán cuándo ven vectoro stringno std::, así que creo que no using namespace stdes mejor. Por lo tanto, defiendo que nunca lo sea using namespace std.

Si cree que debe hacerlo, agregue declaraciones locales usando como using std::vector. Pero pregúntese: ¿Qué valor tiene esto? Una línea de código se escribe una vez (quizás dos), pero se lee diez, cien o mil veces. El esfuerzo de mecanografía ahorrado al agregar una declaración o directiva using es marginal en comparación con el esfuerzo de leer el código.

Con eso en mente, en un proyecto de hace diez años decidimos calificar explícitamente todos los identificadores con sus nombres completos de espacio de nombres. Lo que parecía incómodo al principio se convirtió en rutina en dos semanas. Ahora, en todos los proyectos de toda esa empresa ya nadie usa directivas o declaraciones de uso. (Con una excepción, ver más abajo). Mirando el código (varios MLoC) después de diez años, siento que tomamos la decisión correcta.

He descubierto que, por lo general, quienes se oponen a la prohibición no usinglo han probado para un proyecto. Aquellos que lo han intentado, a menudo lo encuentran mejor que usar directivas / declaraciones después de muy poco tiempo.

Nota: La única excepción es using std::swapqué es necesario (especialmente en código genérico) para recoger sobrecargas swap()que no se pueden poner en el stdespacio de nombres (porque no se nos permite poner sobrecargas de stdfunciones en este espacio de nombres).

sbi
fuente
3
Una especialización de std :: swap sería una especialización completa; no puede especializar parcialmente las plantillas de funciones. Cualquier programa se permitió a especializarse parcialmente cualquier plantilla biblioteca estándar, siempre y cuando que la especialización depende de un tipo definido por el usuario.
CB Bailey
@Charles: Sí, tienes razón, por supuesto, no hay FTPS. Y puedo especializarme en plantillas std, pero no sobrecargarlas. Perdón por ese pedo mental. Corregiré la publicación.
sbi
2
Tampoco creo que la intención de la using namespacedirectiva fuera hacer mecanografía ; más bien, fue para facilitar la lectura , porque, como usted dice, ese código tendrá que leerse decenas, cientos o miles de veces. Y para algunas personas, se lee mucho más fácil y con menos std::desorden. Pero eso probablemente se reduce a la capacidad perceptiva personal; algunas personas lo filtran std::o incluso lo necesitan como guía (como serifas), otras lo apilan y se sienten como en un camino lleno de baches.
Lumi
1
@sbi: No, eso no es objetivo. Depende de si cree que std :: es útil o no. Más desorden -> menos claridad.
Joshua Richardson
2

Los espacios de nombres mantienen el código contenido para evitar la confusión y la contaminación de las firmas de funciones.

Aquí hay una demostración completa y documentada del uso adecuado del espacio de nombres :

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see /programming/11892976/why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

Salida:

Our log: 42
Standard log: 1.43508
Cees Timmerman
fuente
1

using namespace stdimporta el contenido del stdespacio de nombres en el actual. Por tanto, la ventaja es que no tendrá que escribir std::delante de todas las funciones de ese espacio de nombres. Sin embargo, puede suceder que tenga diferentes espacios de nombres que tengan funciones con el mismo nombre. Por lo tanto, es posible que no termine llamando al que desea.

Especificar manualmente en cuáles desea importar stdevita que eso suceda, pero puede resultar en una larga lista de uso al principio de su archivo, que algunos desarrolladores encontrarán desagradable;)!

Personalmente, prefiero especificar el espacio de nombres cada vez que uso use una función, excepto cuando el espacio de nombres es demasiado largo, en cuyo caso pongo algo de uso al principio del archivo.

EDITAR: como se señaló en otra respuesta, nunca debe colocar un using namespaceen un archivo de encabezado, ya que se propagará a todos los archivos, incluido este encabezado y, por lo tanto, puede producir un comportamiento no deseado.

EDIT2: corrigió mi respuesta, gracias al comentario de Charles.

Wookai
fuente
2
using namespace std; importa el contenido del std espacio nombres en el espacio de nombres global. No cambia el espacio de nombres predeterminado. Definir algo en el espacio de nombres global después de using namespace stdno lo colocará mágicamente en el stdespacio de nombres.
CB Bailey
Lo siento, no quise decir esto. Gracias por señalarlo, corregiré mi respuesta.
Wookai
1
Chicos: gracias por las respuestas. Parece que, en general, es más seguro no utilizar 'using namespace std' y evitar la creación de posibles ambigüedades. A fin de cuentas, el uso de 'std :: xxx' me atrae más que declarar una lista de las diversas funciones al principio del archivo fuente, ya que califica sin ambigüedades cuál es la intención de uno.
paoloricardo
1
Cita (excepto cuando el espacio de nombres es demasiado largo). Puede usar el alias de espacio de nombres para ayudar allí. 'espacio de nombres Rv1 = Thor :: XML :: XPath :: Reglas :: Light :: Version1;' Tenga en cuenta los alias y el uso de ambos obedezca las reglas de alcance;
Martin York
0

Al igual que en Java, donde puede usar puede incluir java.util. * O simplemente seleccionar cada clase individualmente, depende del estilo. Tenga en cuenta que no desea uno using namespace stdal comienzo de su archivo / alcance amplio porque contaminará el espacio de nombres y posiblemente tendrá conflictos, anulando el punto de los espacios de nombres. Pero si tiene una función que usa mucho STL, desordena el código para tener una mezcla de sintaxis de prefijos en su lógica y probablemente debería considerar usar using namespace std(cuando usa una variedad de clases) o usings individuales (cuando usa algunas clases a menudo).

Sam Brightman
fuente
0

Esta discusión estará viva siempre que el IDE con el que trabaja no sea lo suficientemente flexible para mostrar u ocultar la información exacta que necesita.

Esto se debe a que el aspecto que desea que tenga su código depende de la tarea en cuestión.

Al crear mi código fuente, prefiero ver exactamente qué clase estoy usando: ¿es std::stringo la BuzFlox::Obs::stringclase?

Al diseñar el flujo de control, ni siquiera me interesan los tipos de variables, pero quiero centrarme en iflas y whilelas y continuelas.

Así que este es mi consejo:

Dependiendo de la audiencia de su código y el poder de sus herramientas, elija la forma que se lea más fácilmente o que proporcione más información.

xtofl
fuente
0

Hay varias formas de solucionarlo.

Primero: use como lo hizo.

Segundo: hazlo namespace S = std;, reduciendo 2 caracteres.

Tercero: uso static.

Cuarto: no use nombres que stduse.


fuente
-1

Cuáles son los pros y los contras de cada uno

La única razón para dejar std :: es que, en teoría, podría volver a implementar todas las funciones STL usted mismo. Entonces sus funciones podrían cambiarse de usar std :: vector a my :: vector sin cambiar el código.

Martin Beckett
fuente
Los espacios de nombres no están realmente diseñados para permitir el reemplazo de nombres con funcionalidades diferentes, pero equivalentes. Están diseñados para evitar conflictos de nombres no deseados.
Michael Burr
Sí, por lo que la única justificación para la directiva 'using' que rompe esto es permitirle cambiar funciones a un nuevo espacio de nombres.
Martin Beckett
Creo que encontrarás una gran cantidad de programadores quejándose de lo molestos que son los espacios de nombres y queriendo tirarlos por la ventana si no hubiera una directiva de uso. Hasta donde yo sé, todos los lenguajes que usan espacios de nombres tienen algo similar a una directiva de uso para sacarlos del camino cuando los quiere fuera del camino. Si las directivas son inútiles, ¿por qué existen en todas partes?
Michael Burr
Creo que el "uso" tenía la intención de permitirle cambiar a implementaciones alternativas en lugar de ahorrar escribir 3 letras. Me gusta usar "std :: Foo" porque sirve como un contrato para el programador que estoy usando el Foo normal y no tienen que verificar. Estoy de acuerdo en que no querría tener que escribir "com.microsoft.visual-studio.standard-library.numbers.int foo", algunas de las declaraciones del iterador en el STL son así. Python hace un buen trabajo al permitirle extraer conjuntos de funciones decoradas o sin decorar de los módulos.
Martin Beckett
-1

Por que no por ejemplo

typedef std::vector<int> ints_t;
ints_t ints1;
....
ints_t ints2;

en lugar de los difíciles de manejar

std::vector<int> ints1;
...
std::vector<int> ints2;

Lo encuentro mucho más legible y es mi estándar de codificación.

Incluso puede usarlo para incluir información semántica para el lector. Por ejemplo, considere los prototipos de funciones

void getHistorgram(std::vector<unsigned int>&, std::vector<unsigned int>&);

cuales el valor de retorno?

Que tal en cambio

typedef std::vector<unsigned int> values_t;
typedef std::vector<unsigned int> histogram_t;
...
void getHistogram(values_t&, histogram_t&); 
lperro
fuente