Ao criar variáveis locais, é correto usar (const) auto&
ou auto
?
por exemplo:
SomeClass object;
const auto result = object.SomeMethod();
ou const auto& result = object.SomeMethod();
Onde SomeMethod () retorna um valor não primitivo - talvez outro tipo definido pelo usuário. Meu entendimento é que const auto& result
está correto, pois o resultado retornado por SomeMethod () chamaria o construtor de cópia para o tipo retornado. Por favor corrija-me se eu estiver errado.
E para tipos primitivos? Suponho que const auto sum = 1 + 2;
esteja correto.
Isso também se aplica a loops for baseados em intervalo?
for(const auto& object : objects)
auto
funciona (exceto para o caso peculiar deinitializer_list
s, que são não deduzido em um contexto de modelo) eauto
digite dedução.Respostas:
auto
eauto &&
cobrem a maioria dos casos:Use
auto
quando precisar de uma cópia local. Isso nunca produzirá uma referência. O construtor de cópia (ou movimentação) deve existir, mas pode não ser chamado, devido à otimização de elisão de cópia .Use
auto &&
quando você não se importar se o objeto é local ou não. Tecnicamente, isso sempre produzirá uma referência, mas se o inicializador for temporário (por exemplo, a função retorna por valor), ele se comportará essencialmente como seu próprio objeto local.Além disso,
auto &&
também não garante que o objeto será modificável. Dado umconst
objeto ou referência, ele irá deduzirconst
. No entanto, a modificabilidade é freqüentemente assumida, dado o contexto específico.auto &
eauto const &
são um pouco mais específicos:auto &
garante que você está compartilhando a variável com outra coisa. É sempre uma referência e nunca temporária.auto const &
é semelhanteauto &&
, mas fornece acesso somente leitura.Não há diferença.
Sim. Aplicando os princípios acima,
auto &&
para a capacidade de modificar e descartar valores da sequência dentro do loop. (Ou seja, a menos que o contêiner forneça uma visualização somente leitura, comostd::initializer_list
, nesse caso, será efetivamente umauto const &
.)auto &
para modificar os valores da sequência de uma forma significativa.auto const &
para acesso somente leitura.auto
para trabalhar com cópias (modificáveis).Você também menciona
auto const
sem referência. Isso funciona, mas não é muito usado porque raramente há uma vantagem para o acesso somente leitura a algo que você já possui.fonte
auto&
parece ser uma boa escolha. Mas useconst auto&
quando quiser adicionar constância que ainda não está lá.auto&&
é para encaminhamento, o que eu acho que acontece com mais frequência do que Sutter pensa. Por exemplo, você pode querer armazenar um valor de retornoauto&&
e então "encaminhá-lo" para duas coisas, como std :: cout para ver o valor para depuração e também passá-lo para alguma outra função. Eu costumava usar o auto && com mais freqüência, mas fui mordido por ele uma ou duas vezes quando fazia coisas inesperadas. Eu gostaria de ter reparado melhor no que deu errado!auto&&
está relacionado a um recurso de linguagem ausente, que deve permitir que qualquer declaração seja dividida em declarações menores. A parte que falta é a extensão da vida ... Eu me esforcei bastante para consertar isso, mas ninguém percebeu. Não dê muito valor ao punditry :)Sim, é correto usar
auto
eauto&
para variáveis locais. Ao obter o tipo de retorno de uma função, também é correto usarauto&
. Isso também se aplica a loops for baseados em intervalo.As regras gerais de uso
auto
são:auto x
quando você deseja trabalhar com cópias.auto &x
quando deseja trabalhar com itens originais e pode modificá-los.auto const &x
quando deseja trabalhar com itens originais e não os modificará.Você pode ler mais sobre o especificador automático aqui .
fonte
auto
usa o mesmo mecanismo de dedução de tipo como modelos, a única exceção de que estou ciente é a das listas brace-init, que são deduzidas porauto
comostd::initializer_list
, mas não deduzidas em um contexto de modelo.auto x = expression;
funciona removendo primeiro todos os qualificadores de referência e cv do tipo da expressão do lado direito e, em seguida, combinando o tipo. Por exemplo, se você deduz
const int& f(){...}
então como e não .auto x = f();
x
int
const int&
A outra forma,
auto& x = expression
não remove os qualificadores cv, portanto, usando o exemplo acima,
auto& x = f()
deduzx
comoconst int&
. As outras combinações apenas adicionam os qualificadores CV.Se você quiser que seu tipo seja sempre deduzido com os qualificadores cv-ref, use o infame
decltype(auto)
em C ++ 14, que usa asdecltype
regras de dedução de tipo.Então, em poucas palavras, se você quiser cópias, use
auto
, se quiser referências, useauto&
. Useconst
sempre que desejarconst
-ness adicional .EDITAR Há um caso de uso adicional,
auto&& x = expression;
que usa as regras de recolhimento de referência, o mesmo que no caso de referências de encaminhamento no código do modelo. Se
expression
for um lvalue, entãox
é uma referência lvalue com os qualificadores cv deexpression
. Seexpression
for um rvalue, entãox
é uma referência rvalue.fonte
rvalues
. Existe alguma maneira simples de testar? E como você pode ter um rvalue cv qualificado? No retorno da função, cv é descartado.auto && x = std::move< const int >( 5 );
irá declararint const && x
, embora sejam raramente usados.Sim. O auto nada mais é do que um tipo deduzido pelo compilador, então use referências onde você normalmente usaria referências e cópias locais (automáticas) onde você normalmente usaria cópias locais. Usar ou não uma referência é independente da dedução de tipo.
Legal? Sim, com o const. Melhor prática? Provavelmente não, não. Pelo menos, não com C ++ 11. Principalmente, se o valor retornado de SomeMethod () já for temporário. Você deseja aprender sobre a semântica de movimentação do C ++ 11, elisão de cópia e otimização de valor de retorno: https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by- valor/
http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199
https://isocpp.org/wiki/faq/ctors#return-by-value-optimization
Sim, tudo bem.
Sim, isso também é bom. Eu escrevo esse tipo de código no trabalho o tempo todo.
fonte