D'autres réponses mentionnent des inconvénients comme «vous ne savez pas vraiment quel est le type d'une variable». Je dirais que cela est largement lié à une convention de dénomination bâclée dans le code. Si vos interfaces sont clairement nommées, vous ne devriez pas avoir à vous soucier du type exact. Bien sûr, auto result = callSomeFunction(a, b);
ça ne vous dit pas grand chose. Mais auto valid = isValid(xmlFile, schema);
vous en dit assez pour l'utiliser valid
sans avoir à vous soucier de son type exact. Après tout, avec juste if (callSomeFunction(a, b))
, vous ne sauriez pas non plus le type. La même chose avec tous les autres objets temporaires de sous-expression. Je ne considère donc pas cela comme un réel inconvénient auto
.
Je dirais que son principal inconvénient est que parfois, le type de retour exact n'est pas celui avec lequel vous voulez travailler. En effet, le type de retour réel diffère parfois du type de retour "logique" en tant que détail d'implémentation / d'optimisation. Les modèles d'expression en sont un excellent exemple. Disons que nous avons ceci:
SomeType operator* (const Matrix &lhs, const Vector &rhs);
Logiquement, nous nous attendrions SomeType
à l'être Vector
, et nous voulons absolument le traiter comme tel dans notre code. Cependant, il est possible qu'à des fins d'optimisation, la bibliothèque d'algèbre que nous utilisons implémente des modèles d'expression, et le type de retour réel est le suivant:
MultExpression<Matrix, Vector> operator* (const Matrix &lhs, const Vector &rhs);
Maintenant, le problème est que MultExpression<Matrix, Vector>
, selon toute vraisemblance, stockera un const Matrix&
et en const Vector&
interne; il s'attend à ce qu'il se convertisse en a Vector
avant la fin de son expression complète. Si nous avons ce code, tout va bien:
extern Matrix a, b, c;
extern Vector v;
void compute()
{
Vector res = a * (b * (c * v));
// do something with res
}
Cependant, si nous avions utilisé auto
ici, nous pourrions avoir des ennuis:
void compute()
{
auto res = a * (b * (c * v));
// Oops! Now `res` is referring to temporaries (such as (c * v)) which no longer exist
}