Muitas respostas razoáveis já. Vou abordar uma analogia que pode ajudar alguns leitores. ::funciona muito parecido com o separador de diretório do sistema de arquivos ' /', ao pesquisar seu caminho para um programa que você gostaria de executar. Considerar:
/path/to/executable
Isso é muito explícito - apenas um executável no local exato na árvore do sistema de arquivos pode corresponder a essa especificação, independentemente do PATH em vigor. Similarmente...
::std::cout
... é igualmente explícito no espaço para nome C ++ "árvore".
Contrastando com esses caminhos absolutos, você pode configurar boas shells do UNIX (por exemplo, zsh ) para resolver caminhos relativos no diretório atual ou em qualquer elemento da PATHvariável de ambiente, por isso PATH=/usr/bin:/usr/local/bin, se você estiver dentro /tmp, então ...
X11/xterm
... seria executado feliz /tmp/X11/xtermse encontrado, mais /usr/bin/X11/xterm, mais /usr/local/bin/X11/xterm. Da mesma forma, digamos que você estava em um espaço para nome chamado Xe teve um " using namespace Y" efeito, então ...
std::cout
... pode ser encontrada em qualquer um ::X::std::cout, ::std::cout, ::Y::std::cout, e possivelmente outros lugares devido à pesquisa dependentes do argumento (ADL, também conhecido como Koenig lookup). Portanto, apenas ::std::couté realmente explícito exatamente exatamente qual objeto você quer dizer, mas felizmente ninguém em seu perfeito juízo jamais criaria sua própria classe / estrutura ou espaço de nome chamado " std", nem qualquer coisa chamada " cout", portanto, na prática, usar apenas std::coutestá bem.
Diferenças notáveis :
1) shells tendem a usar a primeira correspondência usando a ordem de entrada PATH, enquanto o C ++ gera um erro de compilador quando você é ambíguo.
2) No C ++, nomes sem nenhum escopo à frente podem ser correspondidos no namespace atual, enquanto a maioria dos shells do UNIX só fazem isso se você inserir .o PATH.
3) O C ++ sempre pesquisa no espaço para nome global (como ter /implicitamente o seu PATH).
Discussão geral sobre namespaces e explicitação de símbolos
::abc::def::...Às vezes, o uso de "caminhos" absolutos pode ser útil para isolá-lo de qualquer outro espaço de nome que você esteja usando, parte de, mas realmente não tem controle sobre o conteúdo ou mesmo outras bibliotecas que o código de cliente da sua biblioteca também usa. Por outro lado, também o acopla mais firmemente ao local "absoluto" existente do símbolo e você perde as vantagens da correspondência implícita nos espaços para nome: menos acoplamento, mobilidade mais fácil do código entre espaços para nome e código-fonte legível e conciso .
Como em muitas coisas, é um ato de equilíbrio. Os puts lotes C ++ padrão dos identificadores sob std::que são menos "único" do que cout, que os programadores podem usar para algo completamente diferente no seu código (por exemplo merge, includes, fill, generate, exchange, queue, toupper, max). Duas bibliotecas não-padrão não relacionadas têm uma chance muito maior de usar os mesmos identificadores, já que os autores geralmente não têm ou menos consciência um do outro. E as bibliotecas - incluindo a biblioteca C ++ Standard - alteram seus símbolos ao longo do tempo. Tudo isso potencialmente cria ambiguidade ao recompilar o código antigo, principalmente quando há um uso pesado de using namespaces: a pior coisa que você pode fazer nesse espaço é permitirusing namespaces nos cabeçalhos para escapar do escopo dos cabeçalhos, de forma que uma quantidade arbitrariamente grande de código de cliente direto e indireto não consiga tomar suas próprias decisões sobre quais namespaces usar e como gerenciar ambiguidades.
Portanto, um líder ::é uma ferramenta na caixa de ferramentas do programador C ++ para desambiguar ativamente um conflito conhecido e / ou eliminar a possibilidade de ambiguidade futura.
::meios nus referenciam a variável do namespace global / anônimo.