Accueil
|_Accueil Langage C++ |_Définition de templates |_Fonction template |_Classe template |_Utilisation du mot clé typename |_Spécialisation de templates |_Utilisation de types traits |_Les nouveautés C++ 2011 |
Spécialisation de templatesLa spécialisation de template permet de définir plusieurs templates de même nom en garantissant que ce sera toujours le plus spécifique qui sera utilisé pour produire vos fonctions, classes et méthodes. En effet, et théoriquement, un template peut être utilisé pour une infinité de type de données : il envisageable que dans certains cas, ce template ne soit pas le plus approprié. Il est alors possible de définir un template spécialisé pour certains de ces types. Exemple de mise en oeuvre d'une spécialisation de template
Dans l'exemple ci-dessous, un template nommé La fonction main utilise ensuite ces templates en prenant soin de bien tester les trois alternatives.
Notez que la dernière ligne du |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#include <iostream> using namespace std; template <typename T1, typename T2> class Pair { T1 first; T2 second; public: Pair( const T1 & t1, const T2 & t2 ) { this->first = t1; this->second = t2; cout << "Master template" << endl; } }; template <typename T> class Pair<T, int> { T first; int second; public: Pair( const T & t1, int i ) { this->first = t1; this->second = i; cout << "Specialized template 1" << endl; } }; template <typename T> class Pair<double, T> { double first; T second; public: Pair( double d, const T & t2 ) { this->first = d; this->second = t2; cout << "Specialized template 2" << endl; } }; int main( int argc, char * argv[] ) { Pair<const char *, const char *> p1( "toto", "titi" ); Pair<const char *, int> p2( "toto", 2 ); Pair<double, const char *> p3( 3.141592654, "toto" ); //Pair<double, int> p4( 3.141592654, 4 ); // Does not compile: ambiguous declarations return 0; } |
Notez que la dernière ligne du main
, avant le return
,
ne compile pas (c'est pour cela qu'elle est commentée). Effectivement, si le premier type générique est fixé à double
et que le second est fixé à int
,
alors le compilateur pourrait appliquer ces deux spécialisations de même priorité : du coup et dans de tel cas, il préférera s'abstenir de choisir et donc produire une erreur de compilation.
A titre d'information, voici le message d'erreur que produirait le compilateur g++
dans ce cas.
[~/Desktop]$ g++ -o Sample Sample.c Sample.c: In function 'int main(int, char**)': Sample.c:46:25: error: ambiguous class template instantiation for 'class Pair<double, int>' Pair<double, int> p4( 3.141592654, 4 ); // Does not compile: ambiguous declarations ^ Sample.c:18:7: error: candidates are: class Pair<T, int> class Pair<T, int> { ^ Sample.c:30:7: error: class Pair<double, T> class Pair<double, T> { ^ Sample.c:46:25: error: variable 'Pair<double, int> p4' has initializer but incomplete type Pair<double, int> p4( 3.141592654, 4 ); // Does not compile: ambiguous declarations ^ [~/Desktop]$
Si vous souhaitez régler cette erreur de compilation, une solution pourra être de totalement spécialiser le template pour les deux types double
et
int
. Voici un exemple de spécialisation totale.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#include <iostream> using namespace std; template <typename T1, typename T2> class Pair { T1 first; T2 second; public: Pair( const T1 & t1, const T2 & t2 ) { this->first = t1; this->second = t2; cout << "Master template" << endl; } }; template <typename T> class Pair<T, int> { T first; int second; public: Pair( const T & t1, int i ) { this->first = t1; this->second = i; cout << "Specialized template 1" << endl; } }; template <typename T> class Pair<double, T> { double first; T second; public: Pair( double d, const T & t2 ) { this->first = d; this->second = t2; cout << "Specialized template 2" << endl; } }; template <> class Pair<double, int> { double first; int second; public: Pair( double d, int i ) { this->first = d; this->second = i; cout << "Fully specialized template" << endl; } }; int main( int argc, char * argv[] ) { Pair<const char *, const char *> p1( "toto", "titi" ); Pair<const char *, int> p2( "toto", 2 ); Pair<double, const char *> p3( 3.141592654, "toto" ); Pair<double, int> p4( 3.141592654, 4 ); return 0; } |
Voici les résultats produits par l'execution de notre exemple de spécialisation totale du template.
[~/Desktop]$ g++ -o Sample Sample.c $> Essai Master template Specialized template 1 Specialized template 2 Fully specialized template $>
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :