Generics en C++ : pourquoi sont-ils nécessaires et comment utiliser les templates

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
```html

Introduction : que sont les Generics en C++ et pourquoi en avons-nous besoin ?



Dans le monde de la programmation, on rencontre souvent le besoin d'écrire du code qui fonctionne aussi bien avec différents types de données. Par exemple, une fonction de tri de tableau doit pouvoir trier à la fois des nombres entiers, des chaînes de caractères ou des objets personnalisés. Sans mécanisme de programmation générique (generics), il faudrait écrire des fonctions séparées pour chaque type, ce qui entraîne une duplication de code, des erreurs et une complexification de la maintenance.



En C++, ce problème est résolu par les modèles (templates) — un outil puissant qui permet de créer des fonctions et des classes génériques. Le concept de generics en C++ est implémenté précisément via les templates. Ils permettent au programmeur de définir un algorithme ou une structure de données sans se lier à un type spécifique, en substituant le type au moment de la compilation.



Les principaux avantages de l'utilisation des templates :

  • Réduction de la duplication de code — un seul template remplace de nombreuses fonctions surchargées.
  • Sécurité de type — toutes les vérifications de type sont effectuées au moment de la compilation.
  • Performance — les templates n'ajoutent pas de frais généraux lors de l'exécution, car le code est généré pour chaque type spécifique séparément.
  • Flexibilité — il est possible de créer des constructions génériques complexes, y compris des conteneurs (STL) et des algorithmes.


Dans cet article, nous allons détailler comment utiliser les templates en C++, en commençant par des exemples simples et en terminant par des techniques avancées.



Fondamentaux du travail avec les templates de fonctions



La façon la plus simple de se familiariser avec les generics est d'écrire une fonction template. Supposons que nous ayons besoin d'une fonction qui trouve le maximum de deux valeurs. Sans templates, il faudrait écrire des surcharges pour int, double, std::string, etc. Avec les templates, cela se fait une seule fois :



#include <iostream>#include <string>

// Template de fonctiontemplate <typename T>T max(T a, T b) { return (a > b) ? a : b;}

int main() { std::cout << max(10, 20) << std::endl; // int std::cout << max(3.14, 2.71) << std::endl; // double std::cout << max("apple", "orange") << std::endl; // const char* (comparaison de chaînes) return 0;}


Ici, le mot-clé template déclare un modèle, et typename T (ou class T) définit le paramètre de type. Le compilateur génère automatiquement une version de la fonction pour chaque type utilisé. Il est important de noter que les types doivent supporter l'opérateur > — sinon, une erreur de compilation se produira.



On peut également spécifier plusieurs paramètres de type :



template <typename T1, typename T2>void printPair(T1 a, T2 b) {    std::cout << "(" << a << ", " << b << ")" << std::endl;}

// UtilisationprintPair(42, "Hello"); // (42, Hello)


Templates de classes : création de conteneurs universels



Les templates de classes permettent de créer des structures de données génériques — c'est la base de la bibliothèque standard de templates (STL). Examinons un exemple simple de classe template pour un tableau dynamique :



#include <iostream>#include <stdexcept>

template <typename T>class Array {private: T* data; size_t size;public: Array(size_t sz) : size(sz) { data = new T[size]; } ~Array() { delete[] data; } T& operator[](size_t index) { if (index >= size) { throw std::out_of_range("Index out of range"); } return data[index]; } size_t getSize() const { return size; }};

int main() { Array<int> intArray(5); // Tableau d'entiers Array<double> doubleArray(3); // Tableau de nombres à ```

Blogs

Book Recommendations