Quais são os prós / contras de usar a auto
palavra - chave, especialmente em loops?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
Parece que se você não sabe se você tem um iterador para um mapa ou um vector que você não saberia se ao uso first
ou second
ou apenas diretamente acessar propriedades do objeto, não?
Isso me lembra o debate em C # sobre a utilização da palavra-chave var
. A impressão que estou chegando até agora é que, no mundo C ++, as pessoas estão prontas para adotar a auto
palavra-chave com menos esforço do que var
no mundo C #. Para mim, meu primeiro instinto é que gosto de saber o tipo da variável para saber quais operações posso executar nela.
var
? Eu senti falta disso.for (auto& it : x)
(ou sem referência se você quiser copiar)x
e você não sabe mesmo o quex
é, você não deve escrever esse ciclo em primeiro lugar ;-)Respostas:
As motivações em C ++ são mais extremas, pois os tipos podem se tornar muito mais complicados e complexos do que os tipos C # devido à metaprogramação e outras coisas.
auto
é mais rápido de escrever e ler e mais flexível / sustentável do que um tipo explícito. Quero dizer, você quer começar a digitarEsse nem é o tipo completo. Eu perdi alguns argumentos de modelo.
fonte
auto
é para isso. Por design.typedef
ajuda, masauto
ajuda mais.No seu exemplo:
tem que haver uma declaração para
x
visível. Portanto, o tipo deit
deve ser óbvio. Se o tipo dex
não for óbvio, o método é muito longo ou a classe é muito grande.fonte
x
é um nome de variável muito ruim para um contêiner. Em algumas situações, você provavelmente pode apenas olhar para o nome (semanticamente valioso) e inferir as operações possíveis.x
como um exemplo genérico, eu tendem a usar nomes de variáveis bastante descritivos.Objeção ! Pergunta carregada.
Você pode me explicar por que o terceiro código contém
??
, mas o primeiro e o segundo não? Por uma questão de justiça, seu código deve ser o seguinte:Lá. Mesmo problema, mesmo que você não tenha usado
auto
.E em todos os casos, a resposta é a mesma: o contexto é importante . Você não pode falar significativamente sobre um pedaço de código isoladamente. Mesmo se você não tivesse usado modelos, mas algum tipo concreto, isso só teria movido o problema para outro lugar, pois o leitor do seu código precisaria saber sobre a declaração desse tipo.
Se o uso
auto
dessas situações tornar seu código ilegível, você deve tratá-lo como um sinal de aviso de que há algo errado com seu design de código. Obviamente, há casos em que detalhes de baixo nível são importantes (como ao lidar com operações de bits ou API herdada), nos quais um tipo explícito pode ajudar na legibilidade. Mas, em geral - não.Em relação
var
(desde que você o mencionou explicitamente), também há um vasto consenso na comunidade C # sobre o usovar
. Argumentos contra seu uso geralmente são construídos sobre falácias .fonte
T
é tão opaco para o usuário quantoauto
. No entanto, um deve estar bem e o outro não ?! Isso não faz sentido. No caso do OP,T
é um substituto para um tipo arbitrário. No código real, pode ser o uso de modelos(for typename std::vector<T>::iterator…)
ou uma interface de classe. Nos dois casos, o tipo real está oculto para o usuário e, no entanto, rotineiramente escrevemos esse código sem problemas.auto
. É trivial ver quais operaçõesx
suportam do contexto. Na verdade, o tipo lhe dá nenhuma informação adicional: em ambos os casos você precisa de algum secundário (IDE, documentação, conhecimento / memória) para dizer-lhe o conjunto de operações apoiadas.begin
retorno, mas você não sabe o questd::vector<>::iterator
é. E você precisa usar uma ferramenta de programação ruim que não pode fornecer essas informações trivialmente. Isso é altamente complicado. Na realidade, você quer saber tantobegin
eiterator
ou nenhum, e você deve estar usando um IDE ou editor que pode facilmente tornar a informação relevante disponível para você. Todo editor moderno de IDE e programação pode fazer isso.PRÓ
Seu código :
não será compilado, devido ao nome dependente do modelo.
Esta é a sintaxe correta:
Agora veja quanto tempo a declaração de tipo é. Isso explica por que a
auto
palavra - chave foi introduzida. Este :é mais conciso. Então, este é um profissional.
VIGARISTA
Você tem que ter um pouco de cuidado. Com a palavra-chave
auto
, você obtém o tipo que declarou.Por exemplo :
vs
Para concluir: sim, você deveria, mas não o use demais. Algumas pessoas tendem a usá-lo demais e colocam auto em qualquer lugar, como no próximo exemplo:
vs
fonte
auto i = 0
. Culpado. Eu faço isso. Mas isso é porque eu sei que0
é um tipo literalint
. (e uma constante octal ;-))Sim você deveria!
auto
não apaga o tipo; mesmo se você "não souber" o quex.begin()
é, o compilador saberá e relatará um erro se você tentar usar o tipo incorretamente. Além disso, não é incomum emularmap
com avector<pair<Key,Value>>
, portanto, o código usadoauto
funcionará para as duas representações do dicionário.fonte
Sim, você deve usar
auto
como regra padrão. Possui vantagens brutas sobre a especificação explícita do tipo:É aqui que você tem uma escolha. Também há casos em que você não tem escolha:
Desde que você saiba exatamente o que
auto
faz, não há desvantagens.fonte