Outras respostas estão mencionando desvantagens como "você realmente não sabe qual é o tipo de variável". Eu diria que isso está amplamente relacionado à convenção de nomes desleixados no código. Se suas interfaces tiverem um nome claro, você não precisará se importar com o tipo exato. Claro, auto result = callSomeFunction(a, b);
não diz muito. Mas auto valid = isValid(xmlFile, schema);
diz o suficiente para você usar valid
sem ter que se importar com o seu tipo exato. Afinal, com apenas if (callSomeFunction(a, b))
, você também não saberia o tipo. O mesmo com qualquer outro objeto temporário de subexpressão. Portanto, não considero isso uma verdadeira desvantagem auto
.
Eu diria que sua principal desvantagem é que, às vezes, o tipo de retorno exato não é o que você deseja trabalhar. De fato, algumas vezes o tipo de retorno real difere do tipo de retorno "lógico" como um detalhe de implementação / otimização. Modelos de expressão são um excelente exemplo. Digamos que temos o seguinte:
SomeType operator* (const Matrix &lhs, const Vector &rhs);
Logicamente, esperamos SomeType
ser Vector
, e definitivamente queremos tratá-lo como tal em nosso código. No entanto, é possível que, para fins de otimização, a biblioteca de álgebra que estamos usando implementa modelos de expressão, e o tipo de retorno real seja este:
MultExpression<Matrix, Vector> operator* (const Matrix &lhs, const Vector &rhs);
Agora, o problema é que MultExpression<Matrix, Vector>
a vontade em toda a loja de probabilidade de um const Matrix&
e const Vector&
internamente; espera que seja convertido em a Vector
antes do final de sua expressão completa. Se temos esse código, está tudo bem:
extern Matrix a, b, c;
extern Vector v;
void compute()
{
Vector res = a * (b * (c * v));
// do something with res
}
No entanto, se tivéssemos usado auto
aqui, poderíamos ter problemas:
void compute()
{
auto res = a * (b * (c * v));
// Oops! Now `res` is referring to temporaries (such as (c * v)) which no longer exist
}