Inférence de type avec le mot-clé auto en C++

22 Mar 2022 22 Mar 2022 3241 vues ESSADDOUKI Mostafa 6 min de lecture
Introduction et syntaxe de base
1 Introduction au langage C++ 2 Entrée-sortie en C++ - cin et cout 3 Inférence de type avec le mot-clé auto en C++ 4 Classe std::string et les chaînes de caractères en C++ 5 Les structures conditionnelles (if et switch) en C++ (C++17 et C++20) 6 Les boucles en C++ (C++17 et C++20) 7 La gestion des fichiers en C++
Pointeurs et fonctions
8 Introduction aux pointeurs en C++ - Déclaration et interêts 9 Les références en C++ - déclaration et interêts 10 Les tableaux en C++ - Déclaration et interêts 11 Introduction aux fonctions en C++ 12 Passer des arguments à une fonction en C++ 13 Déclarer un paramètre const en C++ 14 Les fonctions Lambda en C++ 15 Fonctions utiles (Mathématiques et caractères) en C++
Programmation OO
16 Classes et objets en C++ 17 Spécificateurs d'accès en C++ 18 Constructeurs et destructeur d'une classe en C++ 19 Fonctions membres en C++ 20 Membres statiques d'une classe en C++ 21 Fonctions en ligne en C++ - inline 22 Fonctions et classes amies en C++ - friend 23 Surcharge des fonctions en C++ 24 Surcharge des opérateurs en C++ 25 Héritage en C++ 26 La gestion d'exceptions en C++ : déclaration, utilisation et personnalisation 27 fonctions et classes templates en C++ 28 Les nouveautés C++20 pour améliorer les templates en C++
Structures de données
29 Introduction aux structures de données 30 Les structures en C++ et la différence avec les structures en C 31 Les listes chaînées en C++ 32 Les piles en C++ 33 File d'attente en C++ 34 Arbre binaire de recherche : définition et mise en oeuvre en C++
La bibliothèque standard (STL)
35 Introduction à la bibliothèque de Template Standard STL 36 Les itérateurs en C++ - définition, déclaration et exemples 37 La classe array en C++ (bibliothèque STL) <array> 38 La classe vector de la bibliothèque STL <vector> 39 La classe deque en C++ ( Bibliothèque STL) 40 La classe list en C++ (bibliothèque STL) <list> 41 La classe stack (Pile) en C++ (bibliothèque STL) <stack> 42 La classe queue (File d'attente) en C++ (bibliothèque STL) <queue> 43 La file d'attente prioritaire (classe priority_queue) - Bibliothèque STL 44 Les ensembles en C++ (Classe set <set> - Bibliothèque STL) 45 Les dictionnaires en C++ : Classe map (Bibliothèque STL) 46 Introduction aux algorithmes de la bibliothèque STL (programmation compétitive) 47 Tri et méthodes associées en C++ - Bibliothèque STL 48 Recherche dichotomique et méthodes associées en C++ - Bibliothèque STL 49 Appliquer un prédicat ou une fonction aux éléments d'une séquence en C++ - Bibliothèque STL 50 Recherche dans une séquence et méthodes associées en C++ - Bibliothèque STL

L'inférence de type avec le mot-clé auto

Définition

L'inférence de type fait référence à la déduction automatique du type de données d'une expression dans un langage de programmation.

Avant C++11, chaque type de données devait être explicitement déclaré au moment de la compilation. Après C++11, de nouveaux mots-clés permettent à un programmeur de laisser la déduction de type au compilateur lui-même.

Avantages

Avec les capacités d'inférence de type, nous pouvons passer moins de temps à écrire des choses que le compilateur connaît déjà.

Important : Comme tous les types sont déduits uniquement dans la phase de compilation, le temps de compilation augmente légèrement mais cela n'affecte pas le temps d'exécution du programme.

Vous utilisez le mot clé auto pour indiquer que le compilateur doit déduire le type d'une variable.

Exemple 1 : Utilisation simple de auto

   
Déduction de types simples C++11 et ultérieur
auto m {10};           // m est de type int
auto n {200UL};        // n est de type unsigned long
auto p {std::numbers::pi};  // p est de type double

Explication :

  • Le compilateur déduit les types de m, n et p à partir des valeurs initiales fournies.
  • 10 est un entier → m est int.
  • 200UL est un unsigned long → n est unsigned long.
  • std::numbers::pi est un double → p est double.

Exemple 2 : Autres formes d'initialisation

Vous pouvez également utiliser la notation fonctionnelle ou d'affectation avec auto :

auto m = 10;           // m est de type int
auto n = 200UL;        // n est de type unsigned long
auto p = std::numbers::pi;  // p est de type double
Remarque importante

Ce n'est pas vraiment ainsi que le mot-clé auto est censé être utilisé. Lorsque vous définissez des variables de types fondamentaux, vous pourriez souvent aussi bien spécifier le type explicitement.

Nous reviendrons sur auto plus tard, où il est appliqué de manière plus appropriée et beaucoup plus utile (avec des itérateurs, des expressions complexes, etc.).

Attention : auto et les initialisateurs entre accolades

Piège à éviter

Vous devez être très prudent lorsque vous utilisez des initialisateurs entre accolades avec le mot-clé auto. Le comportement a changé selon les versions de C++.

Exemple 3 : Évolution du comportement

C++11 et C++14
auto i {10};   // i est std::initializer_list<int> !!!
auto pi = {3.14159};  // pi est std::initializer_list<double>
auto liste1{1, 2, 3}; // liste1 est std::initializer_list<int>
auto liste2 = {4, 5, 6}; // liste2 est std::initializer_list<int>

Dans ces versions, auto i {10}; ne donne pas un int mais une liste d'initialisation !

C++17 et ultérieur
auto i {10};   // i est de type int ✓
auto pi = {3.14159};  // pi est std::initializer_list<double>
auto liste1{1, 2, 3}; // ERREUR : ne compile pas !
auto liste2 = {4, 5, 6}; // liste2 est std::initializer_list<int>

Correction : auto i {10}; donne bien un int maintenant.

auto liste1{1,2,3}; est interdit (plusieurs valeurs).

Exemple concret des différences

/* C++11 et C++14 */
auto i {10};   // i est de type std::initializer_list<int>
auto j = 10;   // j est de type int (notation avec =)
// i et j n'ont pas le même type !

/* C++17 et versions ultérieures */
auto i {10};   // i est de type int (enfin!)
auto j = 10;   // j est de type int (identique)
// i et j ont maintenant le même type
Résumé des règles C++17+
  • auto variable {valeur}; → type = type de valeur (si valeur unique).
  • auto variable = {valeur}; → type = std::initializer_list<T>.
  • auto variable {v1, v2, v3}; → erreur de compilation.
  • auto variable = {v1, v2, v3}; → type = std::initializer_list<T>.

Recommandations pratiques

Pour éviter les pièges

Si votre compilateur prend correctement en charge C++17 :

  • Vous pouvez utiliser l'initialisation entre accolades pour initialiser n'importe quelle variable avec une valeur unique, à condition de ne pas la combiner avec une affectation (=).
  • auto x {5}; → OK, x est un int.
  • auto x = {5}; → attention, x est une liste d'initialisation.
Si votre compilateur n'est pas à jour

Si votre compilateur n'est pas encore complètement à jour (pré-C++17) :

  • Ne jamais utiliser d'initialiseurs entre accolades avec auto.
  • Préférer indiquer explicitement le type ou utiliser l'affectation ou la notation fonctionnelle.
  • auto x = 5; plutôt que auto x {5};

Tableau récapitulatif

SyntaxeC++11/14C++17+
auto x {10};std::initializer_list<int>int
auto x = {10};std::initializer_list<int>std::initializer_list<int>
auto x {1, 2, 3};std::initializer_list<int>Erreur de compilation
auto x = {1, 2, 3};std::initializer_list<int>std::initializer_list<int>
 Exercice pratique

Deviner les types déduits

 Niveau : Débutant

Pour chacune des déclarations suivantes, quel type le compilateur déduira-t-il pour la variable (en supposant un compilateur C++17 conforme) ?

  1. auto a = 42;
  2. auto b {42};
  3. auto c = {42};
  4. auto d = 3.14f;
  5. auto e {3.14};
  6. auto f = {1, 2, 3, 4};
  7. auto g {1, 2, 3, 4};
  8. auto h = "bonjour";
Points clés à retenir
  • auto demande au compilateur de déduire automatiquement le type d'une variable.
  • L'inférence de type a lieu à la compilation, pas à l'exécution.
  • Le comportement de auto avec les accolades a changé entre C++11/14 et C++17.
  • En C++17 : auto x {valeur}; déduit le type de valeur (si unique).
  • En C++17 : auto x = {v1, v2}; déduit std::initializer_list<T>.
  • En C++17 : auto x {v1, v2}; est interdit (erreur).
  • Pour les types simples, spécifier explicitement le type est souvent aussi simple que d'utiliser auto.
  • L'utilité réelle de auto apparaît avec les types complexes (itérateurs, expressions lambda, etc.).

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.