typename vs class dans les templates C++ : guide complet

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Que se cache-t-il derrière les mots "typename" et "class" ? Différences que vous devez absolument connaître

\n\n

Si vous avez déjà écrit des templates en C++, vous avez sûrement rencontré deux mots-clés apparemment interchangeables : typename et class. Cela semble anodin, mais sur Stack Overflow, cette question a rassemblé des milliers de vues. Pourquoi ? Parce que derrière cette simplicité apparente se cache un piège qui peut casser la compilation de votre code.

\n\n

Dans cet article, nous allons une fois pour toutes clarifier : quelle est la différence entre typename et class dans les templates C++, quand ils peuvent être utilisés comme synonymes, et quand cela entraînera une erreur. Pas de blabla — seulement du code, des exemples et des règles claires.

\n\n

Réponse courte : y a-t-il vraiment une différence ?

\n\n

La réponse la plus populaire sur Stack Overflow est : pour déclarer des paramètres de template, il n'y a pas de différence. Vous pouvez écrire :

\n\n
template <typename T> void foo(T t);
\n

ou

\n
template <class T> void foo(T t);
\n\n

Les deux variantes sont parfaitement valides et font la même chose : déclarer un paramètre de template T. Historiquement, class est apparu en premier (dès C++98), et typename a été ajouté plus tard pour souligner que le paramètre peut être non seulement une classe, mais n'importe quel type (int, double, pointeur, etc.).

\n\n

Cependant, le diable se cache dans les détails. Il existe un scénario où typename est obligatoire, et class ne fonctionnera pas. Il s'agit des noms dépendants (dependent names).

\n\n

Le piège principal : les types dépendants (dependent types)

\n\n

Imaginez la situation : vous écrivez un template dans lequel vous accédez à un type imbriqué dans le paramètre du template. Par exemple, vous avez un conteneur et vous voulez obtenir son itérateur :

\n\n
template <typename Container>\nvoid printFirst(const Container& c) {\n    Container::const_iterator it = c.begin(); // ERREUR !\n    std::cout << *it;\n}
\n\n

Pourquoi cela ne se compile-t-il pas ? Parce que Container::const_iterator est un nom dépendant. Le compilateur, lors de l'analyse syntaxique, ne sait pas ce qu'est Container. Peut-être s'agit-il d'une classe, ou peut-être du nom d'une variable statique ? Par défaut, C++ considère que Container::const_iterator est le nom d'une variable (ou d'un membre de données statique), et non un type. Seul le mot-clé typename indique au compilateur : "Hé, c'est un type !".

\n\n

Correction :

\n\n
template <typename Container>\nvoid printFirst(const Container& c) {\n    typename Container::const_iterator it = c.begin(); // OK !\n    std::cout << *it;\n}
\n\n

Important : ici, class ne convient pas. Écrire class Container::const_iterator est une erreur syntaxique. typename est la seule option correcte.

\n\n

Quand utiliser typename plutôt que class ?

\n\n

Retenez une règle simple : typename s'utilise dans deux cas :

\n
    \n
  • Comme paramètre de template (synonyme de class) : template <typename T>
  • \n
  • Pour indiquer qu'un nom dépendant est un type : typename T::value_type
  • \n
\n\n

Quant à class, il ne s'utilise que pour le premier cas. D'ailleurs, de nombreux programmeurs C++ préfèrent typename pour les paramètres afin d'éviter toute confusion avec la déclaration d'une classe.

\n\n

Exemple complet avec explications

\n\n

Analysons un code réel qui illustre la différence entre typename et class dans les templates C++ en pratique :

\n\n
#include <iostream>\n#include <vector>\n#include <list>\n\n// Étape 1 : template avec class (ou typename — sans différence)\ntemplate <class T>\nclass MyContainer {\npublic:\n    // Étape 2 : utilisation de typename pour un type dépendant\n    // T::value_type est un type, et non une                

Blogs

Book Recommendations