UN modèle est un outil simple mais très puissant en C++. L'idée simple est de passer le type de données en paramètre afin que nous n'ayons pas besoin d'écrire le même code pour différents types de données. Par exemple, un éditeur de logiciels peut avoir besoin de sort() pour différents types de données. Plutôt que d'écrire et de gérer plusieurs codes, nous pouvons écrire un seul sort() et transmettre le type de données en paramètre.
C++ ajoute deux nouveaux mots-clés pour prendre en charge les modèles : 'modèle' et 'nom de type' . Le deuxième mot-clé peut toujours être remplacé par le mot-clé 'classe' .
Comment fonctionnent les modèles ?
Les modèles sont développés au moment du compilateur. C'est comme les macros. La différence est que le compilateur effectue une vérification de type avant l'expansion du modèle. L'idée est simple, le code source contient uniquement une fonction/classe, mais le code compilé peut contenir plusieurs copies de la même fonction/classe.
Modèles de fonctions
Nous écrivons une fonction générique qui peut être utilisée pour différents types de données. Des exemples de modèles de fonctions sont sort(), max(), min(), printArray().
Pour en savoir plus sur le sujet, référez-vous à Génériques en C++ .
Exemple:
C++ // C++ Program to demonstrate // Use of template #include using namespace std; // One function works for all data types. This would work // even for user defined types if operator '>' est un modèle surchargéT monMax(T x, T y) { return (x> y) ? x : oui; } int main() { // Appelez myMax pour int cout<< myMax (3, 7)<< endl; // call myMax for double cout << myMax(3,0, 7,0)<< endl; // call myMax for char cout << myMax('g', 'e')<< endl; return 0; }>
Sortir
7 7 g>
Exemple: Exécution Tri à bulles utiliser des modèles en C++
C++ // C++ Program to implement // Bubble sort // using template function #include using namespace std; // A template function to implement bubble sort. // We can use this for any data type that supports // comparison operator template void bubbleSort(T a[], int n) { for (int i = 0; i< n - 1; i++) for (int j = n - 1; i < j; j--) if (a[j] < a[j - 1]) swap(a[j], a[j - 1]); } // Driver Code int main() { int a[5] = { 10, 50, 30, 40, 20 }; int n = sizeof(a) / sizeof(a[0]); // calls template function bubbleSort (un); cout<< ' Sorted array : '; for (int i = 0; i < n; i++) cout << a[i] << ' '; cout << endl; return 0; }>
Sortir
Sorted array : 10 20 30 40 50>
Modèles de cours
Les modèles de classe comme les modèles de fonctions, les modèles de classe sont utiles lorsqu'une classe définit quelque chose qui est indépendant du type de données. Peut être utile pour des classes comme LinkedList, BinaryTree, Stack, Queue, Array, etc.
Exemple:
comment initialiser un tableau en JavaC++
// C++ Program to implement // template Array class #include using namespace std; template tableau de classe {privé : T* ptr ; taille entière ; public : Array(T arr[], int s); annuler l'impression (); } ; modèleTableau::Array(T arr[], int s) { ptr = nouveau T[s]; taille = s ; pour (int je = 0; je< size; i++) ptr[i] = arr[i]; } template tableau vide::print() { pour (int je = 0; je< size; i++) cout << ' ' << *(ptr + i); cout << endl; } int main() { int arr[5] = { 1, 2, 3, 4, 5 }; Array une(arr, 5); un imprimé(); renvoie 0 ; }>
Sortir
1 2 3 4 5>
Peut-il y avoir plus d’un argument pour les modèles ?
Oui, comme les paramètres normaux, nous pouvons transmettre plusieurs types de données comme arguments aux modèles. L’exemple suivant démontre la même chose.
Exemple:
C++ // C++ Program to implement // Use of template #include using namespace std; template classe UNE { T X ; U y; public : A() { cout<< 'Constructor Called' << endl; } }; int main() { Aun; UN b; renvoie 0 ; }>
Sortir
Constructor Called Constructor Called>
Pouvons-nous spécifier une valeur par défaut pour les arguments du modèle ?
Oui, comme les paramètres normaux, nous pouvons spécifier des arguments par défaut aux modèles. L’exemple suivant démontre la même chose.
Exemple:
C++ // C++ Program to implement // Use of template #include using namespace std; template classe A { public : T x ; U y; A() { cout<< 'Constructor Called' << endl; } }; int main() { // This will call A Aun; renvoie 0 ; }>
Sortir
Constructor Called>
Quelle est la différence entre la surcharge de fonctions et les modèles ?
La surcharge de fonctions et les modèles sont des exemples de fonctionnalités de polymorphisme de la POO. La surcharge de fonctions est utilisée lorsque plusieurs fonctions effectuent des opérations assez similaires (pas identiques), les modèles sont utilisés lorsque plusieurs fonctions effectuent des opérations identiques.
Que se passe-t-il lorsqu'il y a un membre statique dans une classe/fonction modèle ?
Chaque instance d'un modèle contient sa propre variable statique. Voir Modèles et variables statiques pour plus de détails.
Qu'est-ce que la spécialisation des modèles ?
La spécialisation des modèles nous permet d'avoir différents codes pour un type de données particulier. Voir Spécialisation des modèles pour plus de détails.
Pouvons-nous transmettre des paramètres non-type aux modèles ?
Nous pouvons transmettre des arguments non-types aux modèles. Les paramètres non-type sont principalement utilisés pour spécifier des valeurs maximales ou minimales ou toute autre valeur constante pour une instance particulière d'un modèle. La chose importante à noter concernant les paramètres non-types est qu'ils doivent être const. Le compilateur doit connaître la valeur des paramètres non-type au moment de la compilation. Parce que le compilateur doit créer des fonctions/classes pour une valeur non-type spécifiée au moment de la compilation. Dans le programme ci-dessous, si nous remplaçons 10000 ou 25 par une variable, nous obtenons une erreur du compilateur.
Exemple:
comment convertir une chaîne en caractèreC++
// C++ program to demonstrate // working of non-type parameters // to templates in C++ #include using namespace std; template int arrMin(T arr[], int n) { int m = max; pour (int je = 0; je< n; i++) if (arr[i] < m) m = arr[i]; return m; } int main() { int arr1[] = { 10, 20, 15, 12 }; int n1 = sizeof(arr1) / sizeof(arr1[0]); char arr2[] = { 1, 2, 3 }; int n2 = sizeof(arr2) / sizeof(arr2[0]); // Second template parameter // to arrMin must be a // constant cout << arrMin (arr1, n1)<< endl; cout << arrMin(arr2, n2); renvoie 0 ; }>
Sortir
10 1>
Voici un exemple de programme C++ pour afficher différents types de données à l'aide d'un constructeur et d'un modèle. Nous effectuerons quelques actions
- passer la valeur du caractère en créant un objet dans la fonction main().
- passer une valeur entière en créant un objet dans la fonction main().
- en passant la valeur float en créant un objet dans la fonction main().
Exemple:
C++ // C++ program to show different data types using a // constructor and template. #include using namespace std; // defining a class template template class info { public: // constructeur de type template info(T A) { cout<< '
' << 'A = ' << A << ' size of data in bytes:' << sizeof(A); } // end of info() }; // end of class // Main Function int main() { // clrscr(); // passing character value by creating an objects infop('x'); // passage d'une valeur entière en créant une info sur l'objet q(22); // passage d'une valeur flottante en créant un objet infor(2,25); renvoie 0 ; }>
Sortir
A = x size of data in bytes:1 A = 22 size of data in bytes:4 A = 2.25 size of data in bytes:4>
Déduction d'argument de modèle
La déduction des arguments de modèle déduit automatiquement le type de données de l’argument transmis aux modèles de classe ou de fonction. Cela nous permet d'instancier le modèle sans spécifier explicitement le type de données.
Par exemple, considérons le modèle de fonction ci-dessous pour multiplier deux nombres :
template t multiply (t num1,t num2) { return num1*num2; }>En général, lorsque l’on veut utiliser la fonction multiplier() pour des entiers, il faut l’appeler ainsi :
multiply (25, 5);>
Mais on peut aussi l'appeler :
multiply(23, 5);>
Nous ne spécifions pas explicitement le type, c'est-à-dire que 1,3 sont des entiers.
La même chose est vraie pour les classes de modèles (depuis C++17 uniquement). Supposons que nous définissions la classe de modèle comme :
template class student{ private: t total_marks; public: student(t x) : total_marks(x) {} };>Si nous voulons créer une instance de cette classe, nous pouvons utiliser l’une des syntaxes suivantes :
générateur de valeurs aléatoires en Java
student stu1(23); or student stu2(24);>
Note: Il est important de noter que la déduction automatique des arguments de modèle pour les classes n'est disponible que depuis C++17, donc si nous essayons d'utiliser la déduction automatique des arguments de modèle pour une classe dans la version précédente, cela générera une erreur.
Exemple de déduction d'argument de modèle
L'exemple ci-dessous montre comment le modèle de classe vectorielle STL déduit le type de données sans être explicitement spécifié.
C++ // C++ Program to illustrate template arguments deduction in // STL #include #include using namespace std; int main() { // creating a vector object without specifying // type vector v1{ 1.1, 2.0, 3.9, 4.909 }; cout << 'Elements of v1 : '; for (auto i : v1) { cout << i << ' '; } // creating a vector object without specifying type vector v2{ 1, 2, 3, 4 }; cout << endl << 'Elements of v2 : '; for (auto i : v2) { cout << i << ' '; } }>
Sortir
Elements of v1 : 1.1 2 3.9 4.909 Elements of v2 : 1 2 3 4>
Note: Le programme ci-dessus échouera à la compilation dans les compilateurs C++14 et inférieurs puisque la déduction des arguments du modèle de classe a été ajoutée en C++17.
Déduction des arguments du modèle de fonction
La déduction des arguments du modèle de fonction fait partie du C++ depuis la norme C++98. Nous pouvons ignorer la déclaration du type d'arguments que nous voulons transmettre au modèle de fonction et le compilateur déduira automatiquement le type en utilisant les arguments que nous avons passés dans l'appel de fonction.
Exemple: Dans l’exemple suivant, nous montrons comment les fonctions en C++ déduisent automatiquement leur type par elles-mêmes.
C++ // C++ program to illustrate the function template argument // deduction #include using namespace std; // defining function template template t multiplier(t premier, t seconde) { return premier * seconde ; } // code du pilote int main() { résultat auto = multiplier(10, 20); std :: cout<< 'Multiplication OF 10 and 20: ' << result << std::endl; return 0; }>
Sortir
Multiplication OF 10 and 20: 200>
Note: Pour les modèles de fonctions qui ont le même type pour les arguments comme template void function(t a1, t a2){}, nous ne pouvons pas transmettre d'arguments de types différents.
comment utiliser l'atelier MySQL
Déduction des arguments du modèle de classe (à partir de C++17)
La déduction des arguments du modèle de classe a été ajoutée en C++17 et fait depuis partie du langage. Cela nous permet de créer les instances de modèles de classe sans définir explicitement les types, tout comme les modèles de fonctions.
Exemple: Dans l’exemple suivant, nous montrons comment le compilateur classe automatiquement les modèles en C++.
C++ // C++ Program to implement Class Template Arguments // Deduction #include #include #include using namespace std; // Defining class template template étudiant de classe {privé : string nom_étudiant ; T total_marks ; public: // Constructeur paramétré student(string n, T m) : student_name(n) , total_marks(m) { } void getinfo() { // impression des détails du cout étudiant<< 'STUDENT NAME: ' << student_name << endl; cout << 'TOTAL MARKS: ' << total_marks << endl; cout << 'Type ID: ' << typeid(total_marks).name() << endl; } }; int main() { student s1('Vipul', 100); // Deduces student student s2('Yash', 98.5); // Deduces student s1.getinfo(); s2.getinfo(); return 0; }>
Sortir
STUDENT NAME: Vipul TOTAL MARKS: 100 Type ID: i STUDENT NAME: Yash TOTAL MARKS: 98.5 Type ID: d>
Ici, je veux dire int et d signifie double.
Pour la métaprogrammation de modèles, r reportez-vous à l’article suivant – Métaprogrammation de modèles .
Prends un Quiz sur les modèles . Java prend également en charge ces fonctionnalités. Java l'appelle génériques .
