Pergunta

Eu tenho dito por outras pessoas que escrever using namespace std; em código está errado, e que eu deveria usar std::cout e std::cin diretamente em vez.

Por que é using namespace std; considerado uma má prática? É ineficiente ou ele arriscar declarar variáveis ??ambíguas (variáveis ??que compartilham o mesmo nome de uma função no namespace std)? Ele afeta o desempenho?

Foi útil?

Solução

Isto não está relacionado ao desempenho em tudo. Mas considere isto: você estiver usando duas bibliotecas chamadas Foo e Bar:

using namespace foo;
using namespace bar;

Tudo bem funciona, você pode chamar Blah() de Foo e Quux() de Bar sem problemas. Mas um dia você atualizar para uma nova versão do Foo 2.0, que agora oferece uma função chamada Quux(). Agora você tem um conflito: Ambos Foo 2.0 e Bar Quux() importação para o namespace global. Isso vai levar algum esforço para correção, especialmente se os parâmetros da função acontecer para corresponder.

Se você tivesse usado foo::Blah() e bar::Quux(), em seguida, a introdução de foo::Quux() teria sido um não-evento.

Outras dicas

Eu concordo com tudo Greg escreveu , mas eu gostaria de adicionar: ele pode até mesmo ficar pior do que Greg disse!

Biblioteca Foo 2.0 poderia introduzir uma função, Quux(), que é uma forma inequívoca melhor correspondência para algumas das suas chamadas para Quux() que o bar::Quux() seu código chamado por anos. Em seguida, seu código ainda compila , mas silenciosamente chama a função errada e Deus sabe o quê. Isso é quase tão ruim quanto as coisas podem ficar.

Tenha em mente que o namespace std tem toneladas de identificadores, muitos dos quais são muito mais comuns (acho list, sort, string, iterator, etc.) que são muito propensos a aparecer em outra código, também.

Se você considerar este improvável: Houve uma pergunta perguntou aqui no estouro de pilha, onde praticamente exatamente isso aconteceu (errado função chamada devido ao prefixo std:: omitido) cerca de meio ano depois que eu dei esta resposta. Aqui é outro exemplo, mais recente de um tal pergunta. Portanto, este é um problema real.


Aqui está mais um ponto de dados: Muitos, muitos anos atrás, eu também costumava achar que é chato ter que tudo o prefixo a partir da biblioteca padrão com std::. Depois trabalhei em um projeto onde foi decidido no início que ambas as directivas using e declarações são proibidos, exceto para escopos de função. Adivinha? Levou a maioria de nós poucas semanas para se acostumar a escrever o prefixo, e depois de mais algumas semanas a maioria de nós até concordou que ele realmente fez o código mais legível . Há uma razão para isso:. Se você gosta mais ou menos longo prosa é subjetivo, mas os prefixos objetivamente adicionar clareza para o código Não só o compilador, mas, também, encontrá-lo mais fácil de ver que identificador é referido.

Em uma década, o projeto cresceu ter vários milhões de linhas de código. Uma vez que essas discussões vêm de novo e de novo, uma vez eu estava curioso como muitas vezes o using (permitido) função escopo realmente foi utilizado no projeto. I grep'd as fontes para isso e só encontrei uma ou duas dúzias de lugares onde ele foi usado. Para mim, isso indica que, uma vez tentou, os desenvolvedores não encontrar std:: bastante doloroso para empregar usando directivas ainda uma vez a cada 100 KLOC mesmo onde ele foi autorizado a ser utilizado.


A linha inferior: Explicitamente prefixo tudo não fazer nenhum mal, leva muito pouco tempo para se acostumar, e tem vantagens objectivas. Em particular, torna o código mais fácil de interpretar pelo compilador e pelos leitores humanos - e que provavelmente deve ser o principal objetivo ao escrever código

.

O problema com a colocação using namespace nos arquivos de cabeçalho de suas classes é que ele força qualquer um que queira usar suas classes (incluindo seus arquivos de cabeçalho) para também ser 'usando' (ou seja, vendo tudo in) os outros namespaces.

No entanto, você pode sentir-se livre para colocar a instrução usando em seus arquivos * .cpp (privados).


Tenha em atenção que algumas pessoas discordam com a minha dizendo "sinto livre" assim - porque, apesar de uma instrução using em um arquivo cpp é melhor do que em um cabeçalho (porque ela não afeta as pessoas que incluir o seu arquivo de cabeçalho), eles acham que ainda não é boa (porque dependendo do código que poderia fazer a implementação da classe mais difícil de manter). Este FAQ tópico diz:

Existe a usar-directiva para código legado C ++ e para facilitar a transição para namespaces, mas você provavelmente não deve usá-lo em uma base regular, pelo menos não em seu novo código C ++.

O FAQ sugere duas alternativas:

  • A usando-declaração:

    using std::cout; // a using-declaration lets you use cout without qualification
    cout << "Values:";
    
  • Apenas digitação std ::

    std::cout << "Values:";
    

Recentemente, correu em uma reclamação sobre Visual Studio 2010 . Descobriu-se que praticamente todos os arquivos de origem tinha essas duas linhas:

using namespace std;
using namespace boost;

Um monte de impulsionar recursos estão indo para o C ++ 0x padrão, e Visual Studio 2010 tem um monte de C ++ 0x apresenta, assim de repente estes programas não foram compilação.

Portanto, evitando using namespace X; é uma forma de futuro-impermeabilização, uma maneira de certificar-se de uma alteração às bibliotecas e / ou arquivos de cabeçalho em uso não vai quebrar um programa.

A versão curta: não use mundial usando declarações ou directivas em arquivos de cabeçalho. Sinta-se livre para usá-los em arquivos de implementação. Aqui está o que Herb Sutter e Andrei Alexandrescu têm a dizer sobre esta questão em C ++ Coding Standards (negrito para dar ênfase é minha):

Resumo

usings Namespace são para sua conveniência, não para você para infligir aos outros:. Nunca escreva um usando declaração ou usando uma diretiva antes de uma diretiva #include

Corolário: Em arquivos de cabeçalho, faça namespace de nível não escrita usando diretivas ou usar declarações; em vez disso, de forma explícita namespace-qualificar todos os nomes. (A segunda regra decorre do primeiro, porque cabeçalhos nunca pode saber o que as outras #includes de cabeçalho poderá aparecer atrás deles.)

Discussão

Em resumo: Você pode e deve usar namespace usando declarações e directivas liberalmente em seus arquivos de implementação após diretivas #include e se sentir bem sobre isso. Apesar de repetidas afirmações em contrário, namespace usando declarações e directivas não são maus e não derrotar o propósito de namespaces. Ao contrário, eles são o que fazem namespaces utilizável .

Não se deve usar usando a diretiva no escopo global, especialmente em cabeçalhos. No entanto, existem situações em que se justifica, mesmo em um arquivo de cabeçalho:

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));
}

Este é melhor do que a qualificação explícita (std::sin, std::cos ...) porque é mais curto e tem a capacidade de trabalhar com o usuário definido tipos de ponto flutuante (via Argumento Dependente Lookup).

Não usá-lo globalmente

É considerado "mau" apenas quando usado globalmente . Porque:

  • Você desorganização do namespace que você está programando.
  • Os leitores terão dificuldade em ver onde um identificador específico vem, quando você usa muitos using namespace xyz.
  • Tudo o que é verdadeiro para outros leitores de seu código-fonte é ainda mais verdadeiro para o leitor mais frequente de que: você mesmo. Volte daqui a um ano ou dois e vejam ...
  • Se você só falar sobre using namespace std que você pode não estar ciente de todas as coisas que você pegar -. E quando você adicionar outra #include ou mudança para uma nova revisão C ++ você pode ter conflitos de nome você não estava ciente de

Você pode usá-lo localmente

Vá em frente e usá-lo localmente (quase) livremente. Isto, naturalmente, o impede de repetição de std:: -. E repetição também é ruim

Um idioma para usá-lo localmente

Em C ++ 03, houve um idioma - código clichê - para implementar uma função swap para suas classes. Sugere-se que você realmente usa um using namespace std local - ou pelo 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(...)`
}

Este faz o seguinte mágica:

  • O compilador escolherá o std::swap para value_, ou seja void std::swap(int, int).
  • Se você tem um void swap(Child&, Child&) sobrecarga implementado o compilador irá escolhê-lo.
  • Se você não ter essa sobrecarga do compilador usará void std::swap(Child&,Child&) e tentar o seu melhor trocar estes.

Com C ++ 11 não há nenhuma razão para usar esse padrão mais. A implementação de std::swap foi mudado para encontrar uma sobrecarga potencial e escolhê-lo.

Se você importar os arquivos de cabeçalho direito de repente você tem nomes como hex , left , plus ou count em seu escopo global. Isso pode ser surpreendente se você não está ciente de que std:: contém esses nomes. Se você também tentar usar esses nomes localmente pode levar a algum confusão.

Se todo o material padrão é em seu próprio namespace você não precisa se preocupar com colisões de nomes com o seu código ou outras bibliotecas.

Os programadores experientes usar o que resolve seus problemas e evitar tudo o que cria novos problemas, e evitam-file-nível do cabeçalho usando-directivas para esta razão exata.

Os programadores experientes também tentar evitar a qualificação cheia de nomes dentro de seus arquivos de origem. Um motivo secundário para isto é que não é elegante para escrever mais código quando o código menos é suficiente a menos que haja boas razões . A principal razão para isso é desligar pesquisa dependentes do argumento (ADL).

O que são essas boas razões ? Às vezes, os programadores explicitamente deseja desativar ADL, outras vezes eles querem disambiguate.

Assim, a seguir estão OK:

  1. Função de nível usando as directivas e usando-declarações dentro implementações funções
  2. -file-level Fonte usando-declarações dentro arquivos de origem
  3. (Às vezes) em arquivo de nível de fonte usando as directivas

Outra razão é surpresa.

Se eu ver cout << blah, em vez de std::cout << blah

Eu acho que é essa cout? É o cout normal? É algo especial?

Eu concordo que não deve ser utilizado em todo o mundo, mas não é tão mau para usar localmente, como em um namespace. Aqui está um exemplo de "O C ++ linguagem de programação" :

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

}

Neste exemplo, resolvemos conflitos de nome potenciais e ambiguidades decorrentes da sua composição.

Nomes declarado explicitamente lá (incluindo nomes declarados usando-declarações como His_lib::String) ter prioridade sobre nomes acessíveis em outro escopo por um utilizando-directiva (using namespace Her_lib).

Também considero uma má prática. Por quê? Apenas um dia eu pensei que a função de um namespace é o material divide então eu não deveria desperdiçá-la com jogar tudo em um saco global. No entanto, se muitas vezes eu uso 'cout' e 'cin', eu escrevo: using std::cout; using std::cin; no arquivo CPP (nunca no arquivo de cabeçalho, uma vez que se propaga com #include). Eu acho que sane ninguém nunca vai citar cout córrego ou cin. ;)

É bom ver código e sabe o que faz. Se eu ver std::cout Eu sei que é o fluxo de cout da biblioteca std. Se eu ver cout então eu não sei. É poderia ser o fluxo de cout da biblioteca std. Ou pode haver um int cout = 0; dez linhas superior na mesma função. Ou uma variável static chamado cout nesse arquivo. Poderia ser qualquer coisa.

Agora, dê uma base de código milhões de linha, que não é particularmente grande, e você estiver procurando por um bug, o que significa que você sabe que há uma linha neste um milhão de linhas que não faz o que é suposto Faz. cout << 1; poderia ler um static int chamado cout, transferi-lo para a esquerda por um pouco, e jogar fora o resultado. Olhando para um bug, eu teria que verificar isso. você pode ver como eu realmente preferem ver std::cout?

É uma dessas coisas que parecem realmente uma boa idéia se você é um professor e nunca teve de escrever e manter qualquer código para ganhar a vida. Eu adoro ver código onde (1) Eu sei o que ele faz; e, (2) Estou confiante de que a pessoa escrevê-lo sabia que ele faz.

É tudo sobre como gerenciar a complexidade. Usando o namespace vai puxar coisas em que você não quer, e, assim, possivelmente torná-lo mais difícil de debug (digo possivelmente). Usando std :: todo o lugar é mais difícil de ler (mais texto e tudo o que).

Cavalos para cursos - gerir a sua complexidade como você pode melhor e se sentir capaz

.
  1. você precisa ser capaz de ler códigos escritos por pessoas que têm estilo diferente e melhores práticas opiniões que você.

  2. Se você estiver usando apenas cout, ninguém fica confuso. Mas quando você tem um monte de namespaces voando ao redor e você vê esta classe e você não está exatamente certo o que ele faz, tendo os atos explícitos de namespace como um comentário de tipos. Você pode ver à primeira vista, 'oh, esta é uma operação de sistema de arquivos' ou 'isso é fazendo coisas rede'.

Considere

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


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

class stringstream {  // uh oh
};

Note que este é um exemplo simples, se você tem arquivos com 20 inclui e outras importações você terá uma tonelada de dependências que percorrer para descobrir o problema. A pior coisa sobre ele é que você pode obter erros não relacionados em outros módulos, dependendo das definições que entrem em conflito.

Não é horrível, mas você vai poupar dores de cabeça por não utilizá-lo em arquivos de cabeçalho ou o namespace global. É provavelmente certo para fazê-lo em âmbitos muito limitado, mas eu nunca tive um problema digitando os extra de 5 caracteres para esclarecer onde minhas funções são provenientes.

Usando muitos namespaces ao mesmo tempo é obviamente uma receita para o desastre, mas usando std APENAS namespace e só std namespace não é tão grande de um negócio na minha opinião, porque redefinição só pode ocorrer por seu próprio código ...

Então, basta considerá-los funciona como nomes reservados, como "int" ou "classe" e que é ele.

As pessoas devem parar de ser tão anal sobre isso. Seu professor estava certo o tempo todo. Usar apenas um namespace; que é o ponto inteiro de usar namespaces primeiro lugar. Você não são supostamente para usar mais de um ao mesmo tempo. A menos que seja o seu próprio. Então, novamente, a redefinição não vai acontecer.

Eu concordo com os outros aqui, mas gostaria de abordar as preocupações sobre a legibilidade - você pode evitar tudo isso simplesmente usando typedefs na parte superior do seu arquivo, função ou declaração de classe.

Eu costumo usá-lo na minha declaração de classe como métodos em uma classe tendem a lidar com tipos de dados semelhantes (os membros) e um typedef é uma oportunidade para atribuir um nome que é significativo no contexto da classe. Isso realmente ajuda a legibilidade nas definições dos métodos de classe.

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

e na implementação:

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

ao contrário:

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

ou

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

Um namespace é um escopo nomeado. Namespaces são usados ??para declarações do grupo relacionado e para manter separado itens separados. Por exemplo, duas bibliotecas separadamente desenvolvidas podem usar o mesmo nome para referir-se a diferentes itens, mas um usuário ainda pode usar tanto:

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
    / / ...
}

Repetindo um nome de namespace pode ser uma distração para ambos os leitores e escritores. Consequentemente, é possível a afirmar que nomes de um namespace especial estão disponíveis sem qualificação explícita. Por exemplo:

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
    / / ...
}

Namespaces fornecem uma poderosa ferramenta para a gestão de bibliotecas diferentes e de diferentes versões código. Em particular, eles oferecem as alternativas programador de como explícita para fazer uma referência a uma não-local nome.

Fonte: Uma visão geral do C ++ linguagem de programação por Bjarne Stroustrup

Um exemplo concreto para esclarecer a preocupação. Imagine que você tem uma situação onde você tem 2 bibliotecas, foo e bar, cada um com seu próprio espaço de nomes:

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

namespace bar {
    ...
}

Agora, vamos dizer que você usar foo e bar junto em seu próprio programa da seguinte forma:

using namespace foo;
using namespace bar;

void main() {
    a(42);
}

Neste momento está tudo bem. Quando você executar o programa é faz alguma coisa '. Mas depois que você bar atualização e vamos dizer que mudou de ser como:

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

Neste ponto, você terá um erro do compilador:

using namespace foo;
using namespace bar;

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

Então, você precisa fazer alguma manutenção para esclarecer que 'a' você quis dizer (ou seja foo::a). Isso é provavelmente indesejável, mas, felizmente, é muito fácil (basta adicionar foo:: na frente de todas as chamadas para a que as marcas compilador como ambígua).

Mas imagine um cenário alternativo onde bar mudou em vez de olhar como este em vez disso:

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

Neste ponto, a sua chamada para a(42) repente se liga a bar::a vez de foo::a e em vez de fazer 'algo' que faz 'algo completamente diferente'. Sem aviso do compilador ou qualquer coisa. Seu programa de apenas silenciosamente começa a fazer algo completamente diferente do que antes.

Quando você usa um namespace que você está arriscando um cenário como este, razão pela qual as pessoas estão desconfortáveis ??usando namespaces. Quanto mais as coisas em um espaço de nomes, maior o risco de conflito, de modo que as pessoas possam estar ainda mais desconfortável usando namespace std (devido ao número de coisas em que namespace) do que outros namespaces.

Em última análise, este é um trade-off entre writability vs confiabilidade / manutenção. Legibilidade pode fator no também, mas eu podia ver os argumentos de que vai de qualquer maneira. Normalmente eu diria confiabilidade e facilidade de manutenção são mais importantes, mas neste caso você vai constantemente pagar o custo writability para um impacto confiabilidade / manutenção bastante raro. O 'melhor' trade-off vai determinar em seu projeto e suas prioridades.

Um exemplo onde usando namespace std lança erro complilation por causa da ambiguidade da contagem, que é também uma função no algoritmo biblioteca.

#include <iostream>

using namespace std;

int count = 1;
int main() {
    cout<<count<<endl;
}

Eu não acho que isso é necessariamente má prática em todas as condições, mas você precisa ter cuidado ao usá-lo. Se você estiver escrevendo uma biblioteca, você provavelmente deve usar os operadores de resolução de escopo com o namespace para manter sua biblioteca de batendo de frente com outras bibliotecas. Para código de nível de aplicação, eu não vejo nada de errado com ele.

Ele não piorar o seu software ou o desempenho do projeto, a inclusão do namespace no início do seu código-fonte não é ruim. A inclusão da instrução using namespace std varia de acordo com suas necessidades e a forma como você está desenvolvendo o software ou projeto.

O namespace std contém o C ++ funções padrão e variáveis. Este namespace é útil quando muitas vezes você usaria o C ++ funções padrão.

Como é mencionado neste página :

A declaração using namespace std é geralmente considerado ruim prática. A alternativa a esta declaração é para especificar o espaço de nomes a que pertence o identificador utilizando o operador de escopo (: :) cada vez que declarar um tipo.

E veja este parecer :

Não há nenhum problema usando "usando namespace std" em seu arquivo de origem quando você faz uso intenso do espaço de nomes e saber com certeza que nada vai colidir.

Algumas pessoas disseram que é uma prática ruim para incluir o using namespace std em seus arquivos de origem porque você está invocando a partir desse namespace todas as funções e variáveis. Quando você gostaria de definir uma nova função com o mesmo nome que outra função contida na namespace std você iria sobrecarregar a função e que poderia gerar problemas devido a compilar ou executar. Ele não irá compilar ou executar como você espera.

Como é mencionado neste página :

Embora a declaração nos salva de std :: digitação sempre queremos acessar uma classe ou tipo definido no namespace std, ele importa a totalidade do namespace std para o namespace atual do programa. Tomemos alguns exemplos para entender por que isso pode não ser uma coisa boa

...

Agora, numa fase posterior do desenvolvimento, queremos usar outra versão do cout que é costume implementado em alguma biblioteca chamado “foo” (para exemplo)

...

Observe como há uma ambiguidade, ao qual biblioteca faz ponto cout para? O compilador pode detectar isso e não compilar o programa. No pior caso, o programa pode ainda compilar mas chamar a função errada, uma vez que nós nunca especificada a que namespace o identificador pertencia.

Com identificadores importados não qualificados você precisa de ferramentas de busca externas, como grep para descobrir onde identificadores são declarados. Isso faz com que o raciocínio sobre correção de programas mais difícil.

"Por que é 'usando namespace std;' considerado uma má prática em C ++? "

eu colocá-lo no sentido inverso:? Por que está digitando 5 caracteres extras é considerado complicado por alguns

Considere por exemplo escrevendo um pedaço de software numérica, por isso que eu consideraria mesmo poluindo o meu espaço global cortando geral "std :: vector" para baixo "vector" quando "vector" é um dos conceitos mais importantes do domínio problema?

Depende de onde ele está localizado. Se é um cabeçalho comum, então você está diminuindo o valor do namespace, fundindo-a no namespace global. Tenha em mente, esta poderia ser uma maneira elegante de fazer globals módulo.

Esta é uma prática ruim, muitas vezes conhecido como poluição namespace global. Problemas podem ocorrer quando mais de um namespace tem o mesmo nome da função com a assinatura, então ele vai ser ambíguo para o compilador para decidir qual deles para ligar e tudo isso pode ser evitado quando você está especificando o namespace com o seu chamada de função como std::cout. Espero que isto ajude. :)

Concordo com os outros - ele está pedindo para conflitos de nome, ambiguidades e, em seguida, o fato é que é menos explícito. Embora eu possa ver o uso de using, a minha preferência pessoal é limitá-lo. Gostaria também de considerar fortemente que alguns outros assinalou:

Se você quiser encontrar um nome de função que pode ser um nome bastante comum, mas você só quer encontrá-lo no espaço de nomes std (ou o inverso - que pretende alterar todas as chamadas que não estão em std namespace, X namespace , ...), então como é que você se propõe a fazer isso? Você poderia escrever um programa para fazer isso, mas não seria melhor gastar tempo trabalhando em seu projeto em si, em vez de escrever um programa para manter seu projeto?

Pessoalmente, eu realmente não me importo o prefixo std::. Eu gosto de olhar mais do que não tê-lo. Eu não sei se isso é porque ele é explícito e me diz "este não é o meu código ... Eu estou usando a biblioteca padrão" ou se é outra coisa, mas eu acho que parece mais agradável. Isso pode ser estranho, dado que só recentemente entrou em C ++ (utilizada e ainda fazer C e outras linguagens por muito mais tempo e C é a minha linguagem favorita de todos os tempos, logo acima de montagem).

Há uma outra coisa, embora seja algo relacionado com o acima exposto e do que outros apontam. Embora isso possa ser uma prática ruim, eu std::name às vezes reserva para versão da biblioteca padrão e nome para implementação específica do programa. Sim, de fato isso poderia mordê-lo e mordê-lo duro, mas tudo se resume ao que eu comecei esse projeto a partir do zero e eu sou o único programador para ele. Exemplo: Eu sobrecarga std::string e chamam string. Eu tenho adições votos. Fiz isso em parte por causa da minha C e Unix tendência (+ Linux) em direcção nomes minúsculas.

Além disso, você pode ter aliases de namespace. Aqui está um exemplo de onde é útil que pode não ter sido referido. I usar o C ++ 11 padrão e especificamente com libstdc ++. Bem, ele não tem suporte completo std::regex. Claro que compila mas ele lança uma exceção ao longo das linhas de que seja um erro no final do programador. Mas é falta de implementação. Então, aqui está como eu resolveu. Instale regex do Boost, vinculá-lo em seguida, eu faço o seguinte para que, quando libstdc ++ tem implementado totalmente, eu só preciso remover este bloco eo código permanece o mesmo:.

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;  
}

Não vou discutir sobre se isso é uma má idéia ou não. Vou no entanto argumentar que mantém limpo para o meu projeto e, ao mesmo tempo faz com que seja específico: True eu tenho que usar impulso, mas eu estou usando-o como o libstdc ++ acabará por tê-lo. Sim, começar seu próprio projeto e começando com um padrão (...) no início vai um longo caminho com a ajuda de manutenção, desenvolvimento e tudo que está envolvido com o projeto!

Editar:
Agora que eu tenho tempo, apenas para esclarecer alguma coisa. Eu realmente não acho que é uma boa idéia usar um nome de uma classe / whatever no STL deliberadamente e mais especificamente no lugar de. A string é a exceção (ignore o primeiro, acima ou segundo aqui, chalaça, se for preciso) para mim como eu não gostava da ideia de 'String'. Como é, eu estou ainda muito inclinado para C e tendenciosa contra C ++. Poupando detalhes, muito do que eu trabalho em ataques C mais (mas foi um bom exercício e uma boa maneira de me tornar um. Aprender outro idioma e b. Tente não ser menos tendenciosa contra objetos / classes / etc que é talvez melhor declarados como menos mente fechada, menos arrogante, mais aceitar.). Mas o que é útil é o que alguns já sugeriu: Eu de fato lista usar (é bastante genérico, não é?), Sort (mesma coisa), para citar dois que causaria um choque nome, se eu fosse fazer using namespace std; e, assim, isso eu prefiro ser específico, no controle e sabendo que se eu pretendo que seja o uso padrão, então eu vou ter que especificá-lo. Simplificando: não umssuming permitido.

E, como para fazer parte regex do impulso de std. Eu faço isso para a futura integração e - mais uma vez, eu admita esse viés é - Eu não acho que isso é tão feio quanto boost::regex:: ... Na verdade isso é uma outra coisa para mim. Há muitas coisas em C ++ que eu ainda ainda têm de vir a aceitar plenamente na aparência e métodos (um outro exemplo: modelos variádicos contra args var [embora eu admita modelos variádicos são muito muito útil!]). Mesmo aqueles que não aceitam que era difícil e eu ainda tenho problemas com eles.

Para responder a sua pergunta eu olhar para ele dessa forma praticamente: um monte de programadores (não todos) invoke namespace std. Portanto, deve ter o hábito de não usar coisas que impinge ou usar os mesmos nomes que o que está no std namespace. Isso é um grande negócio concedido, mas não tanto em comparação com o número de possíveis palavras coerentes e pseudônimos que podem ser vir para cima com rigor.

eu quero dizer realmente ... dizendo "não dependem de este ser presente" é apenas estabelecer-se para contar com ele não estar presente. Você está constantemente indo a ter problemas mutuários trechos de código e constantemente repará-los. Basta manter suas coisas e emprestado definido pelo usuário no escopo limitado como deveriam ser e ser muito parco com globals (honestamente globals deve ser quase sempre o último recurso para fins de "compilar agora, sanidade depois"). Verdadeiramente eu acho que é um mau conselho de seu professor porque usar std irá trabalhar para ambos "cout" e "std :: cout", mas não usando std só irá funcionar para "std :: cout". Você não vai ser sempre o suficiente sorte de escrever todo o seu próprio código.

Nota: Não se concentrar demais em questões de eficiência até que você realmente aprender um pouco sobre como compiladores trabalhar. Com um pouco de experiência de codificação que você não tem que aprender muito sobre eles antes de perceber o quanto eles são capazes de generalizar bom código em algo algo simples. Tão simples como se você escreveu a coisa toda em C. Boa código só é tão complexo como ele precisa ser.

Da minha experiência, se você tiver várias bibliotecas que usos dizem, cout, mas para uma finalidade diferente você pode usar o cout errado.

Por exemplo, se eu digitar, using namespace std; e using namespace otherlib; e digite apenas cout (que passa a ser em ambos), ao invés de std::cout (ou 'otherlib::cout'), você pode usar o errado, e obter erros, é muito mais eficaz e eficiente de usar std::cout.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top