2009-11-17 3 views
2

Je veux être en mesure de définirComment faire pour avoir des surcharges de fonction de modèle accepter des classes dérivées de différentes classes de base?

template <class TX> 
void f(const TX &x){ ... } 
template <class TY> 
void f(const TY &x){ ... } 

où TX doit être dérivé de BaseX et TY doit provenir de la BaseY (comment puis-je préciser ce genre de chose?), Et je veux être en mesure d'appeler comme

f(DerivedX<T>()) 

il est très important que je puisse éviter de spécifier les paramètres du modèle. Est-ce possible, et si oui, comment l'implémenterais-je? Si ce n'est pas possible, y a-t-il un moyen de faire en sorte qu'une fonction modélisée n'accepte que certains types, mais qu'elle soit implicitement instanciée? Je ne peux pas faire que les surcharges de f acceptent la classe de base car j'ai besoin du type de la classe dérivée.

Répondre

6

Vous pouvez utiliser is_base_of de Boost.TypeTraits comme ceci:

#include <boost/type_traits.hpp> 
#include <boost/utility.hpp> 

class BaseX { }; 
class BaseY { }; 

class DerivedX : public BaseX { }; 
class DerivedY : public BaseY { }; 

template <typename TX> 
boost::enable_if<boost::is_base_of<BaseX, TX>, void>::type 
f(const TX& x) 
{ 
} 

int main(int argc, char** argv) 
{ 
    DerivedX x; 
    DerivedY y; 

    f(x); // compiles 
    f(y); // will cause a compilation error 
} 

La bibliothèque est Boost.TypeTraits tête seule, de sorte que vous n'avez pas besoin de lier quoi que ce soit dans

+2

Un addendum - ce que enable_if fait est qu'il a seulement un membre 'type' si la condition est vraie, donc il provoque une erreur de compilation si vous essayez d'utiliser' type' et la condition est fausse. Cependant, en raison d'un principe connu sous le nom de SFINAE (l'échec de substitution n'est pas une erreur), cela indique simplement au compilateur de ne pas choisir cette version du modèle. Si vous en avez un autre pour 'BaseY', le compilateur ne créera pas l'un des deux modèles et sera obligé d'utiliser l'autre. Comme ce sera le seul modèle éligible, il sera sélectionné. – coppro

+0

Ok, j'ai lu à propos de ceux-ci, et ils semblent être ce que je suis après. Le code que vous avez indiqué ne compile pas. –

+0

Désolé, c'était un échec de copier-coller; essayez à nouveau (j'ai supprimé le «vide» supplémentaire de la définition de «f»). Il devrait maintenant compiler (si vous supprimez la ligne 'f (y);', car son but est de montrer ce qui causerait une erreur de compilation). –

-1
template <class TX> 
void f(const BaseX &x){ ... } 
template <class TY> 
void f(const BaseY &x){ ... } 

f<DerivedX>(DerviedX<T>()) 

Cela me semble le plus facile. Vous pouvez utiliser is_base_of boost si vous ne souhaitez pas fournir l'argument de modèle explicite.

+0

Nice.. Première réponse w/is_base_of, et -1. –

Questions connexes