Outras pessoas me disseram que escrever using namespace std;
código está errado e que eu deveria usá std::cout
-lo std::cin
diretamente.
Por que é using namespace std;
considerada uma má prática? É ineficiente ou corre o risco de declarar variáveis ambíguas (variáveis que compartilham o mesmo nome que uma função no std
espaço para nome)? Isso afeta o desempenho?
c++
namespaces
std
using-directives
c++-faq
akbiggs
fonte
fonte
std::literals::chrono_literals
,Poco::Data:Keywords
,Poco::Units
e outras coisas que vai lidar com literais ou truques de legibilidade. Sempre que estiver nos arquivos de cabeçalho ou implementação. Acho que pode ser bom em um escopo de função, mas, além de literais e outras coisas, não é útil.Respostas:
Isso não está relacionado ao desempenho. Mas considere o seguinte: você está usando duas bibliotecas chamadas Foo e Bar:
Tudo funciona bem, e você pode ligar
Blah()
do Foo eQuux()
do Bar sem problemas. Mas um dia você atualiza para uma nova versão do Foo 2.0, que agora oferece uma função chamadaQuux()
. Agora você tem um conflito: o Foo 2.0 e o Bar importamQuux()
para o seu espaço de nomes global. Isso exigirá algum esforço para corrigir, especialmente se os parâmetros de função coincidirem.Se você tivesse usado
foo::Blah()
ebar::Quux()
, a introdução defoo::Quux()
teria sido um não-evento.fonte
#define
é que ele não se restringe aos namespaces, mas atropela toda a base de código. Um alias de espaço para nome é o que você deseja.Concordo com tudo o que Greg escreveu , mas gostaria de acrescentar: pode até piorar do que Greg disse!
A Biblioteca Foo 2.0 pode introduzir uma função
Quux()
,, que é uma correspondência inequivocamente melhor para algumas de suas chamadas doQuux()
que obar::Quux()
código chamado por anos. Então seu código ainda é compilado , mas silenciosamente chama a função errada e sabe o que é Deus. Isso é tão ruim quanto as coisas podem ficar.Tenha em mente que o
std
namespace tem toneladas de identificadores, muitos dos quais são muito mais comuns (penselist
,sort
,string
,iterator
, etc.) que são muito propensos a aparecer em outro código, também.Se você considera isso improvável: Houve uma pergunta feita aqui no Stack Overflow em que praticamente isso aconteceu (função incorreta chamada devido ao
std::
prefixo omitido ) cerca de meio ano depois de eu dar essa resposta. Aqui está outro exemplo mais recente dessa pergunta. Portanto, este é um problema real.Aqui está mais um ponto de dados: muitos anos atrás, eu também costumava achar irritante ter que prefixar tudo da biblioteca padrão
std::
. Depois, trabalhei em um projeto no qual foi decidido desde o início queusing
diretivas e declarações são proibidas, exceto no escopo da função. Adivinha? A maioria de nós levou poucas semanas para se acostumar a escrever o prefixo e, depois de mais algumas semanas, a maioria de nós concordou que realmente tornava o código mais legível . Há uma razão para isso: se você gosta de uma prosa mais curta ou mais longa, é subjetivo, mas os prefixos objetivamente acrescentam clareza ao código. Não apenas o compilador, mas você também acha mais fácil ver a qual identificador é referido.Em uma década, esse projeto cresceu para ter vários milhões de linhas de código. Como essas discussões surgem repetidas vezes, fiquei curioso com que freqüência o escopo da função (permitido)
using
realmente era usado no projeto. Encontrei as fontes e encontrei apenas uma ou duas dúzias de lugares onde era usado. Para mim, isso indica que, uma vez tentados, os desenvolvedores não achamstd::
doloroso o suficiente para empregar o uso de diretivas, mesmo uma vez a cada 100 kLoC, mesmo onde foi permitido o uso.Conclusão: prefixar explicitamente tudo não causa nenhum mal, leva muito pouco tempo para se acostumar e possui vantagens objetivas. Em particular, torna o código mais fácil de interpretar pelo compilador e pelos leitores humanos - e esse provavelmente deve ser o objetivo principal ao escrever código.
fonte
string
aula padrão e, aparentemente, todas as bibliotecas tinham as suas. Diga a você: continuaremos escrevendo nosso códigostd::
e você poderá executá-grep -v std:: | vim
lo enquanto estiver navegando nele. Ou você pode ensinar ao seu editor questd::
é uma palavra-chave que deve ser da mesma cor que a cor do plano de fundo. O que quer que funcione.std::
seja prejudicial. Ele carrega informações muito importantes (ou seja, "o que vier depois faz parte da biblioteca padrão", e ainda é um prefixo bastante curto e compacto. Na maioria das vezes, não há problema algum. Às vezes, você tem algumas linhas de código onde você precisa para se referir a símbolos específicos nostd
namespace muito, e, em seguida, umusing
. declaração em que resolve escopo específico o problema bem, mas no caso geral, não é ruído, que transmite informações valiosas , além de remoção de ambigüidades.std::
, sei que serástd::
sem ter que pensar sobre isso. Se eu verstring
oulist
oumap
por si só, gostaria de saber um pouco.vector
,transform
oudistance
. E esses são apenas exemplos dos muitos nomes muito comuns usados na biblioteca padrão. Sugerir não usá-los por medo ou por uma opinião tendenciosa do recurso de namespace que é parte integrante do C ++ é bastante contraproducente.O problema de colocar
using namespace
os arquivos de cabeçalho de suas classes é que ele força quem quiser usar suas classes (incluindo seus arquivos de cabeçalho) a estar 'usando' (ou seja, vendo tudo) esses outros espaços de nomes.No entanto, você pode se sentir à vontade para colocar uma declaração de uso em seus arquivos * .cpp (privados).
Lembre-se de que algumas pessoas não concordam com o meu ditado "sinta-se à vontade" assim - porque, embora uma
using
declaração em um arquivo cpp seja melhor que em um cabeçalho (porque não afeta as pessoas que incluem seu arquivo de cabeçalho), elas ainda não são bom (porque, dependendo do código, isso dificulta a manutenção da implementação da classe). Esta entrada Super FAQ do C ++ diz:O FAQ sugere duas alternativas:
Uma declaração de uso:
Apenas digitando std ::
fonte
Recentemente, deparei com uma reclamação sobre o Visual Studio 2010 . Aconteceu que praticamente todos os arquivos de origem tinham essas duas linhas:
Muitos recursos do Boost estão sendo incluídos no padrão C ++ 0x, e o Visual Studio 2010 possui muitos recursos C ++ 0x; portanto, de repente, esses programas não estavam sendo compilados.
Portanto, evitar
using namespace X;
é uma forma de proteger o futuro, uma maneira de garantir que uma alteração nas bibliotecas e / ou nos arquivos de cabeçalho em uso não interrompa um programa.fonte
using
fora de uma definição de função e raramente usousing namespace
.Versão curta: não use
using
declarações ou diretivas globais nos 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 esse problema nos padrões de codificação C ++ (o destaque para a ênfase é minha):fonte
using
nunca deve aparecer em um cabeçalho, não estou tão convencido sobre a licença gratuita para colocarusing namespace xyz;
em qualquer lugar do seu código, especialmente sexyz
estiverstd
. Eu uso ousing std::vector;
formulário, já que isso apenas puxa um único elemento do espaço para nome para o escopo pseudo-global, levando a muito menos risco de colisão.using namespace
malgoto
é como o mal. Ambos têm usos válidos, mas 999 vezes em 1000 serão usados incorretamente. Então, sim,using namespace
na fonte você não poluirá o namespace de outras inclusões, puro. Mas ele ainda não o protegerá da "diversão" que surge deusing namespace Foo
+using namespace Bar
com você chamando (Foo implícito: :)baz(xyz)
e de repente a quebra de código (sem alterações relacionadas) só porqueBar::baz()
foi adicionada em algum lugar, o que simplesmente é melhor match (e, portanto, agora é chamado)Não se deve usar a
using
diretiva no escopo global, especialmente nos cabeçalhos. No entanto, há situações em que é apropriado, mesmo em um arquivo de cabeçalho:Isso é melhor que a qualificação explícita (
std::sin
,std::cos
...), porque é mais curta e tem a capacidade de trabalhar com tipos de ponto flutuante definidos pelo usuário (por meio da pesquisa dependente de argumento (ADL)).fonte
using std::cos;
,using std::sin
, Etc. A questão, porém, é que qualquer bem concebidouserlib
vai ter o seusin
ecos
dentro de seu próprio namespace, bem, então isso realmente não ajudá-lo. (A menos que haja umusing namespace userlib
antes deste modelo e isso seja tão ruim quantousing namespace std
- e o escopo não seja limitado.) Além disso, a única função como essa que eu já vi acontecer éswap
e, nesses casos, eu recomendaria apenas a criação de um modelo especializaçãostd::swap
e evitar todo o problema.template<typename T> void swap(MyContainer<T>&, MyContainer<T>&)
(Não há nenhum modelo de função especialização parcial (FTPS), por isso às vezes você precisa de recorrer a uma sobrecarga em seu lugar.x
tiver um ou mais "namespaces associados" (por exemplo, se tiver sido definido emnamespace userlib
), qualquer chamada de função que se pareçacos(x)
parecerá adicionalmente nesses namespaces - sem necessidadeusing namespace userlib;
prévia de qualquer . Zan Lynx é certo (e C ++ pesquisa de nome é bizantino ...)Não use globalmente
É considerado "ruim" somente quando usado globalmente . Porque:
using namespace xyz
.using namespace std
você, pode não estar ciente de todas as coisas que captura - e quando adiciona outra#include
ou muda para uma nova revisão de C ++, pode haver conflitos de nome dos quais não estava ciente.Você pode usá-lo localmente
Vá em frente e use-o localmente (quase) livremente. Evidentemente, isso impede que você repita
std::
- e a repetição também é ruim.Um idioma para usá-lo localmente
No C ++ 03, havia um idioma - código padrão - para implementar uma
swap
função para suas classes. Foi sugerido que você realmente usasse um localusing namespace std
- ou pelo menosusing std::swap
:Isso faz a seguinte mágica:
std::swap
forvalue_
, ievoid std::swap(int, int)
.void swap(Child&, Child&)
implementada, o compilador a escolherá.void std::swap(Child&,Child&)
e tentará sua melhor troca.Com o C ++ 11, não há mais razão para usar esse padrão. A implementação de
std::swap
foi alterada para encontrar uma potencial sobrecarga e escolhê-la.fonte
swap
em primeiro lugar não seja mais tão importante no C ++ 11, já que ostd::swap
próprio é mais flexível (usa a semântica de movimentação). Masstd::swap
escolher automaticamente sua própria troca personalizada, isso é absolutamente novo para mim (e eu realmente não acredito nisso).using std::swap;
vez deusing namespace std;
. O idioma mais específico tem menos efeitos colaterais e, portanto, torna o código mais sustentável.swap
, e vários outros lugares no padrão foram alterados para dizer que eles chamamswap
assim (NB, como mencionado acima,using std::swap
é o caminho certo, nãousing namespace std
). Masstd::swap
ele próprio não foi enfaticamente alterado para encontrar outroswap
e usá-lo. Sestd::swap
for chamado,std::swap
será usado.using std::swap
Porém, pode ser mais prudente digitar localmente, reduzir o espaço para nome local e, ao mesmo tempo, criar código de auto-documentação. Raramente você está interessado em todo o espaço para nome padrão, então escolha as partes que mais lhe interessam.Se você importar os arquivos de cabeçalho direito de repente você tem nomes como
hex
,left
,plus
oucount
no seu âmbito global. Isso pode ser surpreendente se você não souber questd::
contém esses nomes. Se você também tentar usar esses nomes localmente, poderá causar certa confusão.Se todo o material padrão estiver em seu próprio espaço para nome, você não precisa se preocupar com colisões de nomes com seu código ou outras bibliotecas.
fonte
distance
. ainda prefiro nomes não qualificados sempre que possível, uma vez que isso aumenta a legibilidade para mim. além disso, acho que o fato de que geralmente não qualificamos as coisas no discurso oral e estamos dispostos a gastar tempo resolvendo possíveis ambiguidades, significa que tem valor ser capaz de entender o que se está falando sem qualificações e aplicado à fonte código que significa que está estruturado de forma a ficar claro o que é, mesmo sem qualificações.<iomanip>
. Ainda assim, bom argumento.Outra razão é surpresa.
Se eu vejo
cout << blah
, em vez destd::cout << blah
pensar: o que é issocout
? Isso é normalcout
? É algo especial?fonte
cout
é um mau exemplo, porque todos o reconhecem. Mas imaginefuture
em um aplicativo financeiro. É um contrato para comprar ou vender algo em uma data especificada? Não, não é. Se o código dissesse questd::future
você não seria tão facilmente confuso.Programadores experientes usam o que resolve seus problemas e evita o que cria novos problemas, além de evitar diretivas de uso no nível do arquivo de cabeçalho por esse motivo exato.
Programadores experientes também tentam evitar a qualificação completa de nomes em seus arquivos de origem. Uma razão menor para isso é que não é elegante escrever mais código quando menos código é suficiente, a menos que haja boas razões . Um dos principais motivos disso é desativar a pesquisa dependente de argumento (ADL).
Quais são essas boas razões ? Às vezes, os programadores explicitamente desejam desativar o ADL, outras vezes desejam desambiguar.
Portanto, o seguinte é OK:
fonte
Concordo que não deve ser usado globalmente, mas não é tão ruim usar localmente, como em um
namespace
. Aqui está um exemplo de "A linguagem de programação C ++" :Neste exemplo, resolvemos possíveis conflitos de nome e ambiguidades decorrentes de sua composição.
Os nomes declarados explicitamente lá (incluindo nomes declarados por declarações de uso como
His_lib::String
) têm prioridade sobre nomes disponibilizados em outro escopo por uma diretiva de uso (using namespace Her_lib
).fonte
Eu também considero uma prática ruim. Por quê? Apenas um dia pensei que a função de um espaço para nome é dividir as coisas, por isso não devo estragar tudo ao jogar tudo em uma bolsa global.
No entanto, se eu geralmente uso 'cout' e 'cin', escrevo:
using std::cout; using std::cin;
no arquivo .cpp (nunca no arquivo de cabeçalho como ele se propaga#include
). Eu acho que ninguém sã jamais nomeará um fluxocout
oucin
. ;)fonte
É bom ver o código e saber o que ele faz. Se eu vejo
std::cout
, sei que é ocout
fluxo dastd
biblioteca. Se eu vejocout
, não sei. Ele poderia ser ocout
fluxo dastd
biblioteca. Ou pode haverint cout = 0;
dez linhas mais altas na mesma função. Ou umastatic
variável chamadacout
nesse arquivo. Poderia ser qualquer coisa.Agora pegue uma base de código de um milhão de linhas, que não é particularmente grande, e você está procurando por um bug, o que significa que você sabe que há uma linha nesse milhão de linhas que não faz o que deveria fazer.
cout << 1;
poderia ler umstatic int
nomecout
, deslocá-lo para a esquerda um pouco e jogar fora o resultado. Procurando por um bug, eu teria que verificar isso. Você pode ver como eu realmente prefiro verstd::cout
?É uma dessas coisas que parece realmente uma boa idéia se você é professor e nunca teve que escrever e manter nenhum código para viver. Adoro ver código onde (1) eu sei o que ele faz; e (2) estou confiante de que a pessoa que o escreveu sabia o que faz.
fonte
É tudo sobre gerenciamento de complexidade. Usar o espaço para nome puxa coisas que você não deseja e, portanto, dificulta a depuração (eu digo possivelmente). Usar std :: em todo o lugar é mais difícil de ler (mais texto e tudo isso).
Cavalos para cursos - gerencie sua complexidade da melhor maneira possível e se sinta capaz.
fonte
Considerar
Observe que este é um exemplo simples. Se você tiver arquivos com 20 inclusões e outras importações, terá várias dependências para resolver o problema. O pior é que você pode obter erros não relacionados em outros módulos, dependendo das definições em conflito.
Não é horrível, mas você evitará dores de cabeça ao não usá-lo nos arquivos de cabeçalho ou no espaço de nomes global. Provavelmente está tudo bem em escopos muito limitados, mas nunca tive problemas ao digitar os cinco caracteres extras para esclarecer de onde vêm minhas funções.
fonte
Você precisa ler o código escrito por pessoas com opiniões diferentes sobre estilo e práticas recomendadas.
Se você estiver usando apenas
cout
, ninguém fica confuso. Mas quando você tem muitos namespaces voando por aí e vê essa classe e não sabe exatamente o que faz, ter o namespace explícito atua como um tipo de comentário. Você pode ver à primeira vista, "oh, isso é uma operação de sistema de arquivos" ou "que está fazendo coisas de rede".fonte
Usar muitos namespaces ao mesmo tempo é obviamente uma receita para o desastre, mas usar apenas o namespace
std
e o namespacestd
não é tão importante na minha opinião porque a redefinição só pode ocorrer pelo seu próprio código ...Portanto, considere-as como nomes reservados, como "int" ou "class", e é isso.
As pessoas devem parar de ser tão analistas sobre isso. Seu professor estava certo o tempo todo. Basta usar um espaço para nome; esse é o objetivo de usar espaços para nome em primeiro lugar. Você não deve usar mais de um ao mesmo tempo. A menos que seja seu. Então, novamente, a redefinição não acontecerá.
fonte
min
,end
eless
aparecem nostd::
namespace. Mais ainda, agora questd::
possui milhares de símbolos, é útil que o leitor saiba de onde vem um novo símbolo que talvez eles não saibam.Concordo com os outros aqui, mas gostaria de abordar as preocupações relacionadas à legibilidade - você pode evitar tudo isso usando simplesmente typedefs na parte superior do seu arquivo, função ou declaração de classe.
Normalmente, eu o uso na minha declaração de classe, pois os 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 seja significativo no contexto da classe. Isso realmente ajuda a legibilidade nas definições dos métodos de classe.
e na implementação:
em oposição a:
ou:
fonte
Um exemplo concreto para esclarecer a preocupação. Imagine que você tem uma situação em que possui duas bibliotecas
foo
ebar
, cada uma com seu próprio espaço para nome:Agora, digamos que você use
foo
ebar
juntos em seu próprio programa, da seguinte maneira:Neste ponto, está tudo bem. Quando você executa seu programa, ele 'faz alguma coisa'. Mas depois você atualiza
bar
e digamos que mudou para:Neste ponto, você receberá um erro do compilador:
Portanto, você precisará fazer alguma manutenção para esclarecer que 'a' significava
foo::a
. Isso é indesejável, mas felizmente é bem fácil (basta adicionarfoo::
antes de todas as chamadas paraa
que o compilador marcar como ambíguo).Mas imagine um cenário alternativo em que a barra mudou para ficar assim:
Nesse ponto, sua ligação de
a(42)
repente se liga aobar::a
invés defoo::a
e em vez de fazer 'algo', ele faz 'algo completamente diferente'. Nenhum aviso do compilador ou qualquer coisa. Seu programa silenciosamente começa a fazer algo completo diferente do que antes.Quando você usa um espaço para nome, está arriscando um cenário como esse, e é por isso que as pessoas se sentem desconfortáveis usando espaços para nome. Quanto mais coisas em um espaço para nome, maior o risco de conflito, para que as pessoas fiquem ainda mais desconfortáveis usando o espaço para nome
std
para (devido ao número de coisas nesse espaço para nome) do que outros espaços para nome.Em última análise, este é um compromisso entre gravabilidade vs. confiabilidade / manutenção. A legibilidade também pode levar em consideração, mas eu pude ver argumentos para isso de qualquer maneira. Normalmente, eu diria que a confiabilidade e a manutenção são mais importantes, mas, neste caso, você pagará constantemente o custo da gravabilidade por um impacto relativamente raro na confiabilidade / manutenção. A melhor opção será determinada em seu projeto e em suas prioridades.
fonte
Um espaço para nome é um escopo nomeado. Os espaços para nome são usados para agrupar declarações relacionadas e manter itens separados. Por exemplo, duas bibliotecas desenvolvidas separadamente podem usar o mesmo nome para se referir a itens diferentes, mas um usuário ainda pode usar os dois:
Repetir um nome de espaço para nome pode ser uma distração para leitores e escritores. Conseqüentemente, é possível afirmar que nomes de um espaço para nome específico estão disponíveis sem qualificação explícita. Por exemplo:
Os espaços para nome fornecem uma ferramenta poderosa para o gerenciamento de diferentes bibliotecas e de diferentes versões de código. Em particular, eles oferecem ao programador alternativas de como é explícito fazer referência a um nome não local.
Fonte: Uma visão geral da linguagem de programação C ++ por Bjarne Stroustrup
fonte
Um exemplo em que
using namespace std
gera um erro de compilação devido à ambiguidade da contagem, que também é uma função na biblioteca de algoritmos.fonte
::count
--problema resolvido. Normalmente, você terá mais coisas do namespace std do que de outros lugares; portanto, manter a diretiva using namespace pode economizar a digitação.Isso não piora o desempenho do seu software ou projeto. A inclusão do espaço para nome no início do seu código-fonte não é ruim. A inclusão das
using namespace std
instruções varia de acordo com suas necessidades e a maneira como você está desenvolvendo o software ou projeto.O
namespace std
contém as funções e variáveis padrão do C ++. Esse espaço para nome é útil quando você costuma usar as funções padrão do C ++.Algumas pessoas disseram que é uma prática ruim incluir os
using namespace std
arquivos de origem porque você está chamando desse espaço de nome todas as funções e variáveis. Quando você deseja definir uma nova função com o mesmo nome que outra função contida no,namespace std
você sobrecarrega a função e isso pode gerar problemas devido à compilação ou execução. Não será compilado ou executado conforme o esperado.fonte
Não acho que seja necessariamente uma má prática sob todas as condições, mas você precisa ter cuidado ao usá-la. Se você estiver escrevendo uma biblioteca, provavelmente deverá usar os operadores de resolução de escopo com o espaço para nome para impedir que sua biblioteca se incomode com outras bibliotecas. Para o código no nível do aplicativo, não vejo nada de errado com ele.
fonte
"Por que 'using namespace std;' considerada uma má prática em C ++? "
Digo o contrário: por que digitar cinco caracteres extras é considerado complicado por alguns?
Considere, por exemplo, escrever um software numérico. Por que eu consideraria poluir meu espaço de nome global cortando "std :: vector" geral em "vetor" quando "vetor" é um dos conceitos mais importantes do domínio do problema?
fonte
cout << hex << setw(4) << i << endl;
é mais fácil de ler do questd::cout << std::hex << std::setw(4) << i << std::endl;
std::map<std::string,std::pair<std::string,std::string>>
é horrível em comparação commap<string,pair<string,string>>
.Eu concordo com os outros - está pedindo conflitos de nome, ambiguidades e, em seguida, o fato é que é menos explícito. Embora eu possa ver o uso de
using
, minha preferência pessoal é limitá-lo. Eu também consideraria fortemente o que alguns outros apontaram:Se você deseja encontrar um nome de função que possa ser um nome bastante comum, mas somente no
std
espaço para nome (ou o inverso - você deseja alterar todas as chamadas que não estão no espaço para nomestd
, espaço para nomeX
, ...), então como você se propõe a fazer isso?Você poderia escrever um programa para fazê-lo, mas não seria melhor gastar tempo trabalhando no seu projeto em vez de escrever um programa para mantê-lo?
Pessoalmente, na verdade não me importo com o
std::
prefixo. Eu gosto do visual mais do que não tê-lo. Não sei se é porque é explícito e me diz "esse não é o meu código ... estou usando a biblioteca padrão" ou se é outra coisa, mas acho que parece melhor. Isso pode ser estranho, já que eu entrei recentemente em C ++ (usei e ainda faço C e outras linguagens por muito mais tempo e C é minha linguagem favorita de todos os tempos, logo acima do assembly).Há uma outra coisa, embora esteja um pouco relacionada ao que foi dito acima e ao que outros apontam. Embora isso possa ser uma prática ruim, às vezes eu reservo
std::name
a versão da biblioteca padrão e o nome da implementação específica do programa. Sim, de fato, isso pode te morder e te morder com força, mas tudo se resume ao fato de eu ter iniciado esse projeto do zero, e eu sou o único programador para ele. Exemplo: eu sobrecarregostd::string
e chamostring
. Eu tenho adições úteis. Eu fiz isso em parte por causa da minha tendência C e Unix (+ Linux) para nomes em letras minúsculas.Além disso, você pode ter alias de namespace. Aqui está um exemplo de onde é útil que pode não ter sido referido. Eu uso o padrão C ++ 11 e especificamente com libstdc ++. Bem, ele não tem
std::regex
suporte completo . Certamente, ele compila, mas gera uma exceção ao longo das linhas de ser um erro no final do programador. Mas é falta de implementação.Então, aqui está como eu resolvi isso. Instale a regex do Boost e vincule-a. Em seguida, faça o seguinte para que, quando o libstdc ++ for totalmente implementado, eu precise apenas remover esse bloco e o código permanecer o mesmo:
Não vou discutir se isso é uma má ideia ou não. No entanto, argumentarei que ele o mantém limpo para o meu projeto e, ao mesmo tempo, o torna específico: É verdade que preciso usar o Boost, mas estou usando-o como o libstdc ++ eventualmente o terá. Sim, iniciar seu próprio projeto e começar com um padrão (...) desde o início ajuda muito na manutenção, desenvolvimento e tudo o que está envolvido no projeto!
Apenas para esclarecer uma coisa: na verdade, não acho que seja uma boa ideia usar o nome de uma classe / o que quer que seja no STL deliberadamente e mais especificamente no lugar de. A string é a exceção (ignore o primeiro, acima ou o segundo aqui, trocadilhos, se necessário) para mim, pois eu não gostei da ideia de 'String'.
Como é, ainda sou muito tendencioso em relação a C e tendencioso em relação a C ++. Detalhes poupadores, muito do que eu trabalho se encaixa mais em C (mas foi um bom exercício e uma boa maneira de me obrigar a. Aprender outro idioma eb. Tentar não ser menos tendencioso contra objetos / classes / etc, o que talvez seja melhor declarado menos mente fechada, menos arrogante e mais receptiva.). Mas o que é útil é o que alguns já sugeriram: eu realmente uso list (é bastante genérico, não é?) E ordeno (a mesma coisa) para nomear dois que causariam um conflito de nomes se eu o fizesse
using namespace std;
, e assim para esse fim, prefiro ser específico, controlar e saber que, se pretender que seja o uso padrão, terei que especificá-lo. Simplificando: não é permitido assumir.E quanto a fazer parte da regex do Boost
std
. Faço isso para integração futura e - novamente, admito que isso é parcialidade - não acho que seja tão feio quantoboost::regex:: ...
. De fato, isso é outra coisa para mim. Ainda há muitas coisas em C ++ que ainda tenho que aceitar totalmente em aparência e métodos (outro exemplo: modelos variados versus argumentos var [embora eu admita que modelos variados sejam muito úteis!]). Mesmo aqueles que eu aceito foram difíceis, e ainda tenho problemas com eles.fonte
std
espaço para nome é um comportamento indefinido e, portanto, nunca deve ser feito.De minhas experiências, se você tem várias bibliotecas que usam o say
cout
, mas para um propósito diferente, pode usar o erradocout
.Por exemplo, se eu digitar,
using namespace std;
eeusing namespace otherlib;
digitar apenascout
(o que acontece em ambos), em vez destd::cout
(ou'otherlib::cout'
), você poderá usar o incorreto e obter erros. É muito mais eficaz e eficiente de usarstd::cout
.fonte
Com identificadores importados não qualificados, você precisa de ferramentas de pesquisa externas, como grep, para descobrir onde os identificadores são declarados. Isso dificulta o raciocínio sobre a correção do programa.
fonte
Depende de onde está localizado. Se for um cabeçalho comum, você estará diminuindo o valor do espaço para nome, mesclando-o no espaço para nome global. Lembre-se de que essa pode ser uma maneira interessante de tornar os módulos globais.
fonte
Essa é uma prática ruim, geralmente conhecida como poluição de namespace global. Podem ocorrer problemas quando mais de um espaço para nome tem o mesmo nome da função com a assinatura; será ambíguo para o compilador decidir qual chamar e tudo isso pode ser evitado quando você especificar o espaço para nome com a sua chamada de função
std::cout
. Espero que isto ajude. :)fonte
Para responder à sua pergunta, eu a encaro da seguinte forma: muitos programadores (nem todos) invocam o namespace std. Portanto, deve-se ter o hábito de NÃO usar coisas que colidem ou usam os mesmos nomes do que está no espaço de nomes std. Isso é bastante concedido, mas não tanto em comparação com o número possível de palavras coerentes e pseudônimos que podem ser apresentados estritamente.
Quero dizer realmente ... dizer "não confie nisso estando presente" é apenas configurá-lo para confiar que NÃO está presente. Você sempre terá problemas para emprestar trechos de código e repará-los constantemente. Apenas mantenha seu material definido pelo usuário e emprestado em um escopo limitado, como deve ser, e seja MUITO poupador de globais (honestamente, os globais devem quase sempre ser o último recurso para fins de "compilar agora, sanidade posterior"). Na verdade, acho que é um mau conselho do seu professor, porque usar std funcionará tanto para "cout" quanto "std :: cout", mas NÃO usar std funcionará apenas para "std :: cout". Você nem sempre terá a sorte de escrever todo o seu próprio código.
NOTA: Não se concentre muito em questões de eficiência até aprender um pouco sobre como os compiladores funcionam. Com um pouco de experiência em codificação, você não precisa aprender muito sobre eles antes de perceber o quanto eles são capazes de generalizar um bom código em algo simples. Tão simples quanto se você tivesse escrito tudo em C. Um bom código é tão complexo quanto precisa.
fonte
<algorithm>
, por exemplo), parece um pouco exagerado imaginar que as mesmas pessoas poderiam evitar com segurança esses identificadores. Examine seu próprio código e me diga que você nunca tem uma variável ou função chamadacount
. Oudistance
, oulog
,destroy
,launch
,visit
,beta
,sample
,messages
,clamp
,erase
,copy
,modulus
,left
, etc. Para não mencionar todos os identificadores ainda não nostd
que vai quebrar seu código quando C ++ 35 sai ...