2010-11-28 8 views
2

J'ai une fonction de gabarit que je m'attends à être modélisée pour différents types à différents endroits.
Le problème est que je voudrais savoir au moment de la compilation s'il existe une spécialisation pour le type donné pour générer de deux manières différentes un autre modèle.Les modèles C++ peuvent-ils vérifier si une fonction a été surchargée pour un type donné?

template<typename T> 
bool tobool(const T&){ throw Exception("Can't cast to bool");}; 
template<> bool tobool<bool>(const bool &value){ return value;} 

Je sais que vous pouvez tester la fonction existance comme dans here.

Y a-t-il une chance de savoir si le tobool a été spécialisé? Imaginez que je veux générer un isbool() qui retourne true si tobool() a été spécialisé et renvoie false sinon.

+1

Ai-je bien compris? : Vous voulez une métafonction qui pour chaque type T montre si tobool a été spécialisé pour T? –

+0

Oui, j'ai besoin de savoir si T utilise un langage générique ou spécialisé. –

+3

Donc, au moment de la compilation, vous pouvez vérifier son existence et faire quoi avec le résultat? –

Répondre

3

En tant que (un peu laid et fragile) solution de contournement, vous pourriez avoir besoin d'une spécialisation struct plutôt qu'une fonction et inclure une constante de classe pour indiquer si le struct est spécialisé:

template <typename T> 
struct ToBool { 
    static bool tobool(const T&); 
    static const bool specialized = false; 
}; 

Une autre option est de définir uniquement tobool dans les spécialisations. De cette façon, ToBool<Foo>::tobool(f) ne compilera pas pour toutes les classes Foo que ToBool n'a pas été spécialisé pour.

En alternative à tobool, vous pouvez utiliser des opérateurs de conversion explicites si vous avez le contrôle sur les classes à convertir.

class Foo { 
public: 
    operator bool(); 
    ... 
}; 
... 
    Foo f; 
    if (f) ... 

Si le type n'a pas de conversion bool (bien, une conversion à un type numérique ou pointeur, qui ont tous deux conversions standard pour Bool), le programme ne sera pas compilé. Voila, compilez le temps de vérifier une conversion.

Si vous ne voulez pas de conversion implicite en bool, vous pouvez définir un opérateur! et utiliser un double-bang pour la conversion explicite (bien que ce ne soit pas aussi lisible):

class Foo { 
public: 
    bool operator!(); 
    ... 
}; 

... 
    Foo f; 
    if (!!f) ... 
0

La réponse à votre question spécifique est la suivante: Non, vous ne pouvez pas vérifier si T utilise le modèle primaire ou spécialisé. La question de @Martin York est très bonne: pourquoi diable voudriez-vous vérifier cela? :)

+0

Parce qu'il y aura un modèle de classe qui a une méthode isbool() qui doit renvoyer true si la classe était spécialisée et false si ce n'était pas le cas. –

Questions connexes