Muchas respuestas razonables ya. Voy a incluir una analogía que puede ayudar a algunos lectores. ::funciona muy parecido al separador de directorio del sistema de archivos ' /', cuando busca en su ruta un programa que le gustaría ejecutar. Considerar:
/path/to/executable
Esto es muy explícito: solo un ejecutable en esa ubicación exacta en el árbol del sistema de archivos puede coincidir con esta especificación, independientemente de la RUTA vigente. Similar...
::std::cout
... es igualmente explícito en el "árbol" del espacio de nombres C ++.
En contraste con tales rutas absolutas, puede configurar buenos shells UNIX (por ejemplo, zsh ) para resolver rutas relativas bajo su directorio actual o cualquier elemento en su PATHvariable de entorno, por lo que si PATH=/usr/bin:/usr/local/bin, y estuviera "en" /tmp, entonces ...
X11/xterm
... correría feliz /tmp/X11/xtermsi lo encontraran, de lo contrario /usr/bin/X11/xterm, de lo contrario /usr/local/bin/X11/xterm. Del mismo modo, digamos que estaba en un espacio de nombres llamado Xy tenía un " using namespace Y" en efecto, entonces ...
std::cout
... se puede encontrar en cualquiera de ::X::std::cout, ::std::cout, ::Y::std::cout, y posiblemente en otros lugares debido a las operaciones de búsqueda argumento dependiente (ADL, también conocido como búsqueda Koenig). Entonces, solo ::std::coutes realmente explícito sobre exactamente a qué objeto te refieres, pero afortunadamente nadie en su sano juicio crearía su propia clase / estructura o espacio de nombre llamado " std", ni nada llamado " cout", por lo que en la práctica usar solo std::coutestá bien.
Diferencias notables :
1) los shells tienden a usar la primera coincidencia usando el orden PATH, mientras que C ++ da un error de compilación cuando has sido ambiguo.
2) En C ++, los nombres sin ningún alcance inicial pueden coincidir en el espacio de nombres actual, mientras que la mayoría de los shells de UNIX solo lo hacen si se coloca .en el PATH.
3) C ++ siempre busca el espacio de nombres global (como tener /implícitamente su PATH).
Discusión general sobre espacios de nombres y explicidad de símbolos
El uso de ::abc::def::..."rutas" absolutas a veces puede ser útil para aislarlo de cualquier otro espacio de nombres que esté usando, parte de, pero realmente no tiene control sobre el contenido o incluso otras bibliotecas que el código del cliente de su biblioteca también usa. Por otro lado, también lo acopla más estrechamente a la ubicación "absoluta" existente del símbolo, y pierde las ventajas de la coincidencia implícita en los espacios de nombres: menos acoplamiento, movilidad más fácil del código entre espacios de nombres y código fuente más conciso y legible .
Como con muchas cosas, es un acto de equilibrio. Los C ++ estándar puts un montón de identificadores en virtud std::de que son menos "única" que cout, que los programadores pueden utilizar para algo completamente diferente en su código (por ejemplo merge, includes, fill, generate, exchange, queue, toupper, max). Dos bibliotecas no estándar no relacionadas tienen una probabilidad mucho mayor de usar los mismos identificadores que los autores generalmente no se conocen entre sí. Y las bibliotecas, incluida la biblioteca estándar de C ++, cambian sus símbolos con el tiempo. Todo esto potencialmente crea ambigüedad al volver a compilar el código antiguo, especialmente cuando ha habido un uso intensivo de using namespaces: lo peor que puede hacer en este espacio es permitirusing namespaces en encabezados para escapar de los ámbitos de los encabezados, de modo que una cantidad arbitrariamente grande de código de cliente directo e indirecto no puede tomar sus propias decisiones sobre qué espacios de nombres usar y cómo gestionar las ambigüedades.
Entonces, un líder ::es una herramienta en la caja de herramientas del programador C ++ para desambiguar activamente un choque conocido y / o eliminar la posibilidad de ambigüedad futura ...
::medios desnudos hacen referencia a la variable del espacio de nombres global / anónimo.