Enquanto leio o padrão do Google, você não pode usar a using namespace foo;
diretiva em nenhum lugar. Essa diretiva traz tudo declarado no espaço para nome e é uma causa comum de colisões e comportamento inesperado. Outros citaram um muito comum: você tem seu próprio método max ou min em algum lugar e ele colide em um arquivo src em que alguém inclui um cabeçalho no seu método e depois dizusing namespace std;
Em certos lugares, é permitido ter uma declaração de uso, que é da forma using ::foo::bar;
As pessoas gostam de usar diretivas em seu código, pois economiza muita digitação, mas isso traz riscos. Se você possui um arquivo com muitas instruções cout, entendo que não quero digitar std :: cout centenas de vezes, mas você pode simplesmente dizer usando :: std :: cout. Trato-os como declarações de variáveis: escopo-los onde são necessários. Se uma função em um arquivo de 10 precisar gravar a saída, não declare o caminho cout na parte superior, coloque-a nessa função que está realizando a saída real.
#include <ostream>
//using namespace std; // NO!
//using ::std::cout; // less bad than using namespace, but I prefer to scope it
int main(int argc, char** argv)
{
int rc = do_some_stuff(argc, argv);
using ::std::endl;
if (rc) { // print the success report
using ::std::cout;
cout << "The test run completed. The return code was " << rc << '.' << endl;
} else {
using ::std::cerr;
cerr << "Unable to complete the test run." << endl;
}
return 0 == rc;
}
Isso é um pouco extremo, com apenas algumas linhas produzindo resultados, mas você entendeu.
Outra coisa que se pode fazer é alias ou typedef para minimizar a digitação. Não acho que std :: seja tão ruim assim, mas temos um enorme conjunto de fontes com várias dezenas de módulos e, às vezes, precisamos escrever códigos como esse console_gui::command_window::append("text")
. Isso fica entediante depois de um tempo e causa muitas longas filas. Eu sou a favor de algo como
typedef console_gui::command_window cw;
cw::append("text");
desde que os aliases sejam feitos em um escopo local e mantenham contexto suficiente para tornar o código legível.
std::endl
para a liberação explícita emstdout
/stderr
normalmente é supérfluo, esses fluxos estão vinculados astdout
/ destderr
qualquer maneira. Até atrasa um pouco as coisas.Isso ocorre porque: 1) derrota todo o objetivo dos espaços para nome, que é reduzir a colisão de nomes; 2) disponibiliza ao espaço de nomes global o espaço de nome inteiro especificado com a diretiva using.
Por exemplo, se você incluir e definir sua própria função max (), ela colidirá com std :: max ().
http://en.cppreference.com/w/cpp/algorithm/max
A preferência é usar std :: member_you_wish_to_use porque indica explicitamente qual espaço para nome usar.
fonte
std::max()
com o prefixo do espaço para nome. Ou estou enganado?using
diretivas, porque nesse caso, ela quebraria sua função max () se você tivesse definido uma e incluído <algoritmo>. Este é um caso simples, mas você nunca sabe o que pode quebrar. Você precisaria conhecer a biblioteca inteira para ter certeza de que não a quebrou, mas não pode saber se o seu código quebraria (por exemplo, colisão de nomes) no futuro.Citando o link que você fornece:
O estilo do Google proíbe o uso de espaços para nome no contexto global, mas permite fazê-lo nos locais.
Em todos os lugares em que o uso da declaração afeta apenas uma parte limitada e claramente visível do código, é perfeitamente aceitável.
Quando você polui o contexto global, o código não relacionado é afetado (por implicação, usando o cabeçalho). Nada acontece quando você faz isso no contexto local.
fonte
Você fez. A recomendação apenas se aplica à
using namespace
diretiva (que é comumente referida comoabusing namespace
, não totalmente humorística). É altamente preferido que você use o nome completo de uma função ou objeto, comostd::cout
.fonte
Embora a pergunta já tenha respostas úteis, um detalhe parece ser muito curto.
A maioria dos programadores fica um pouco confusa com a
using
palavra - chave e as descrições denamespace
uso, mesmo que tentem aprender pesquisando a referência, porque declaração e diretiva são equivalentes, ambas são palavras longas relativamente abstratas, começando com d .Os identificadores nos espaços para nome são acessíveis nomeando explicitamente o espaço para nome:
pode haver muito mais teclas para digitar. Mas também pode diminuir a importância do seu código, se a maioria dos identificadores tiver o prefixo da mesma maneira. A
using
palavra-chave ajuda a evitar essas desvantagens do espaço para nome. Comousing
funciona no nível do compilador (não é macro), seu efeito dura todo o escopo em que é usado. É por isso que o estilo do Google restringe seu uso a escopos bem definidos, como classes nos arquivos de cabeçalho ou funções nos arquivos cpp.... é claro que há uma diferença entre usar declaração
e usando diretiva
Se usado em escopos enormes, o último leva a muito mais confusão.
fonte
Aqui está:
Ao escrevê-lo dessa maneira, evitamos ADL propensas a erros, além de usar diretivas e declarações.
Isso pretende ser uma resposta sarcástica. :-D
Estou com Herb Sutter no Google neste. Dos padrões de codificação C ++:
Você pode ficar obcecado com possíveis conflitos no espaço de nome que provavelmente nunca se manifestarão e provavelmente não serão difíceis de corrigir em um evento astronomicamente raro, evitando cuidadosamente as
using
diretivas e especificando explicitamente tudo o que você usa (até os operadores) comusing
declarações ou apenas vá em frente e comeceusing namespace std
. Eu recomendo este último do ponto de vista da produtividade.O contrário, se você me perguntar, e acredito que Sutter acima concorda.
Agora, ao longo da minha carreira, encontrei cerca de três conflitos no espaço de nomes como resultado direto de
using
diretivas em bases de código que abrangem dezenas de milhões de LOC. No entanto, nos três casos, eles estavam em arquivos de origem que abrangiam mais de 50.000 linhas de código legado, originalmente escritas em C e depois bastardizadas para C ++, executando uma lista eclética maciça de funções díspares, incluindo cabeçalhos de uma dúzia de bibliotecas diferentes e tendo uma lista épica#includes
que se estendeu por uma página. Apesar da bagunça épica, eles não eram muito difíceis de corrigir, pois causavam erros de compilação no OSX (o único SO em que o código não conseguiu compilar), não erros de execução. Não organize seu código dessa maneira assustadora e você ficará bem.Dito isto, evitar tanto
using
directivas e declarações em arquivos de cabeçalho. Isso é simplesmente retardado. Mas para arquivos de origem, e especialmente aqueles que não têm uma página inteira cheia de#include
diretivas, eu diria que não se preocupe se você não estiver trabalhando no Google.fonte