Laissez le compilateur choisir le type
À la page précédente, vous avez vu que toute variable C++ possède un type fixe - int, double, std::string, etc. Écrire ce type à la main convient pour int count = 0;, mais cela devient bruyant dès que les types s'allongent. Le mot-clé auto (C++11 et versions ultérieures) laisse le compilateur déduire le type à partir de la valeur que vous affectez : vous écrivez la valeur une fois et laissez le compilateur compléter le reste.
L'idée clé : auto n'est pas du typage dynamique. Chaque variable possède toujours un seul type concret, verrouillé à la compilation. auto vous évite simplement de l'écrire.
Pourquoi auto mérite sa place
Pour des types courts et évidents, auto count = 0; et int count = 0; sont tout aussi lisibles. Là où auto paie vraiment, c'est avec les noms de types longs et répétitifs - le genre qu'on obtient avec les conteneurs et les itérateurs de la bibliothèque standard.
Comparez la version verbeuse à la version avec auto :
// Sans auto - le type est écrit deux fois, en pratique
std::vector<std::pair<std::string, int>>::iterator it = scores.begin();
// Avec auto - le compilateur connaît déjà le type
auto it = scores.begin();
Les deux déclarent exactement le même type d'itérateur. La seconde est plus facile à lire et ne se désynchronisera pas si vous changez plus tard scores pour un autre conteneur.
La voici dans un programme complet :
auto dans les boucles for basées sur un intervalle
L'endroit le plus courant où vous rencontrerez auto est la boucle for basée sur un intervalle. Vous ne voulez presque jamais écrire le type de l'élément à la main, et la façon dont vous écrivez le auto détermine si vous obtenez une copie ou une référence.
Trois variantes que vous verrez, et ce que chacune signifie :
for (auto x : v)-xest une copie de chaque élément. Économique pourint, gaspilleur pour les gros objets.for (auto& x : v)-xest une référence ; vous pouvez modifier les éléments sur place.for (const auto& x : v)-xest une référence en lecture seule. Utilisez-la quand vous avez seulement besoin de lire.
Ce programme suivant modifie le conteneur via auto& :
Piège : écrivez for (auto n : nums) (sans &) dans cette boucle et n *= 10 ne modifierait silencieusement que la copie, laissant nums intact. Le compilateur ne vous avertira pas - la boucle ne fait simplement rien d'utile.
Ce que auto supprime
Un auto simple déduit le type de la même manière qu'un paramètre de fonction passé par valeur : il supprime le const de premier niveau, les références et volatile. Cela signifie que auto vous donne toujours une copie neuve et modifiable, sauf si vous demandez autre chose.
Si vous voulez conserver le const ou éviter la copie, vous ajoutez les qualificateurs vous-même. Le principe consiste à décorer auto exactement comme vous décoreriez n'importe quel type :
Donc auto déduit le type de base ; &, const et * sont des réglages que vous ajoutez par-dessus. auto est le type, const auto& est une référence en lecture seule vers celui-ci.
Erreurs courantes et pièges
auto supprime l'effort de frappe, pas le besoin de comprendre les types. Quelques pièges attrapent les débutants :
Vous devez initialiser. auto n'a rien à déduire à partir d'une déclaration vide, donc ceci est une erreur de compilation pure et simple :
auto x; // error: declaration of 'auto x' has no initializer
auto y = 0; // ça va
Les littéraux entiers sont des int, pas des double. auto half = 1 / 2; déduit int et stocke 0, parce que 1 / 2 est une division entière avant que auto ne le voie. Le type suit la valeur :
auto supprime la référence - attention aux surprises de copie pendante. Si une fonction renvoie une référence et que vous la capturez avec un auto simple, vous obtenez une copie, ce qui est parfois un véritable problème de performance dans une boucle critique (une copie profonde d'un gros objet à chaque itération). Recourez à const auto& quand vous voulez dire « regarder, pas emporter ».
Ne masquez pas le type quand il compte. auto result = compute(); convient quand le type de retour de compute est évident d'après le contexte, mais si un lecteur doit partir à la chasse pour savoir ce qu'est réellement result, écrire le type peut être le choix le plus aimable. auto sert à réduire le bruit, pas à masquer l'intention.
Suite : Constantes et const
Vous avez maintenant vu que auto supprime délibérément const à moins que vous ne demandiez à le conserver - ce qui soulève la question évidente : que garantit réellement const, et quand devriez-vous marquer une valeur comme immuable en premier lieu ? La page suivante creuse const, les expressions constantes et pourquoi « le mettre en const par défaut » est l'une des habitudes les plus utiles en C++.
Questions fréquentes
Que fait le mot-clé auto en C++ ?
auto indique au compilateur de déduire le type de la variable à partir de son initialiseur. auto x = 5; fait de x un int ; auto y = 3.14; fait de y un double. Le type est fixé à la compilation - auto n'est pas du typage dynamique, c'est un raccourci pour ne pas écrire le type vous-même.
auto conserve-t-il const et les références en C++ ?
Non. Un auto simple supprime le const de premier niveau, les références et volatile. Si la source est const int& r, alors auto x = r; donne une simple copie int. Pour les conserver, vous l'indiquez explicitement : utilisez const auto& pour lier une référence en lecture seule sans copier.
Peut-on déclarer une variable avec auto sans l'initialiser ?
Non. auto x; est une erreur de compilation car il n'y a pas d'initialiseur à partir duquel le compilateur pourrait déduire un type. Toute variable auto doit recevoir une valeur au point de sa déclaration.