comment faire un type de type if else selon le modèle c ++?

// template specialization #include  using namespace std; // class template: template  class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () { //if(T.type==int)//how to do this or something similar? //do this if an int return ++element; //if(T.type==char) //if ((element>='a')&&(element<='z')) //element+='A'-'a'; //return element; } }; 

Je sais comment écrire une spécialisation de modèle et effectuer une définition de classe entière distincte uniquement pour le type char.

Mais si je voulais tout gérer en un seul bloc de code?

Comment puis-je vérifier si T est un int ou un char?

Vous pouvez utiliser typeid :

 if (typeid(T) == typeid(int)) 

Ou vous pouvez utiliser le trait de type std::is_same :

 if (std::is_same::value) 

Ce que vous voulez est probablement quelque chose comme une compilation si . Malheureusement, C ++ 11 n’a pas de support natif pour une telle construction de langage.

Cependant, si vous voulez juste vérifier si deux types sont identiques, le trait de type std::is_same<> devrait vous aider:

 #include  // <== INCLUDE THIS STANDARD HEADER // class template: template  class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () { if (std::is_same::value) // <== THIS IS HOW YOU WOULD USE IT return ++element; if (std::is_same::value) // <== THIS IS HOW YOU WOULD USE IT { if ((element>='a') && (element<='z')) element+='A'-'a'; } return element; } }; 

Cependant, gardez à l'esprit que la condition est évaluée au moment de l'exécution , même si la valeur de is_same::value est connue au moment de la compilation. Cela signifie que les twigs true et false de l'instruction if doivent être compilées !

Par exemple, ce qui suit ne serait pas légal:

 if (std::is_same::value) { cout << element; } else if (std::is_same::value) { element->print(); // Would not comstack when T is int! } 

De plus, comme Xeo l'a correctement souligné dans les commentaires, le compilateur émettra probablement des avertissements, car votre condition sera toujours évaluée comme étant true ou false , de sorte qu'une des deux twigs contiendra du code inaccessible.

Vous pouvez utiliser une spécialisation de modèle explicite

 #include  using namespace std; // class template: template  class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase(); }; template<> int mycontainer::increase(){ return ++element; } template<> char mycontainer::increase(){ if ((element>='a')&&(element<='z')) element+='A'-'a'; return element; } int main(){ mycontainer A(10); mycontainer B('x'); cout << A.increase() < 

Que diriez-vous d’une simple surcharge?

 // in the private section static int& do_increase(int& i){ return ++i; } static char& do_increase(char& c){ if(c >= 'a' && c <= 'z') c += 'A' - 'a'; return c; } template static U& do_increase(U& arg){ // some default implementation? return arg; } 

(Notez que la norme ne garantit pas l’ordre alphabétique des valeurs numériques d’un caractère.)

Ensuite, appelez simplement cela en tant que return do_increase(element); .

La solution habituelle consiste à transmettre à une fonction surchargée un argument supplémentaire. Quelque chose comme:

 template  class MyContainer { T increase( int const* ) { /* special treatment for int */ } T increase( ... ) { /* default treatment */ } public: T increase() { return increase( (T const*)0 ); } }; 

Avec un peu d’imagination, vous pouvez faire toutes sortes de distinctions. Si vous créez les fonctions cible avec les modèles d’arguments supplémentaires, vous pouvez même utiliser SFINAE: concevez l’argument factice pour que la substitution de type de modèle échoue et que la fonction ne soit pas prise en compte dans l’ensemble de surcharge. Et comme toutes les fonctions sont en ligne, il est probable qu’il n’y aura pas de surcharge supplémentaire, à condition d’optimiser.

Cela va dans le sens de la réponse d’Andy Prowls, mais tout est fait lors de la compilation en utilisant une classe d’aides minimale avec spécialisation.

Dans ce cas, vous avez un assistant qui effectue la spécialisation, mais vous pouvez également demander à la classe d’assistance de prendre un booléen, puis d’utiliser quelque chose comme std::is_same::value pour transmettre cette valeur en tant que paramètre de modèle.

 template  struct myContainerHelper; { // General Case static inline T increase(T element) { return ++element; } }; template <> struct myContainerHelper { // Specific case static inline char increase(char element) { if ((element>='a')&&(element<='z')) element+='A'-'a'; return element; } }; template  class mycontainer { T element; public: mycontainer (T arg) {element=arg;} T increase () { return myContainerHelper::increase(element); } }; 

Cela vous permet de spécialiser uniquement la fonction unique à la place de la classe entière. J’utilise une classe de modèles avec la statique car je suis habitué aux limitations VS2012 avec la spécialisation partielle pour les modèles de fonctions.