2011-01-03 3 views
2

J'ai une classe de modèle dans laquelle j'ai une fonction normale. Mais je veux activer cette fonction normale seulement pour certaines instanciations d'une classe template. J'ai regardé boost :: enable_if et cela ne correspond pas exactement à mes besoins/peut-être que je ne suis pas capable de l'utiliser pour mon besoin.Activation sélective de la fonction de classe de modèle

typedef boost::mpl::vector< bool, int, double > CheckTypes; 

template<class X> 
class P 
{ 
    void init(int x, 
     typename boost::enable_if< boost::mpl::contains<CheckTypes, X> >::type* dummy = 0); 
}; 

Quelqu'un peut-il aider mw à résoudre ce problème? Une chose importante est que la solution ne devrait rien attendre du code appelant. Et la classe est explicitement instanciée.

Merci, Gokul.

+0

Lorsque vous dites "activer", voulez-vous dire "cette fonction n'existe même pas si vous instanciez avec les types X, Y ou Z?" – templatetypedef

+0

Je veux que la fonction n'existe que pour bool, int et double dans mon exemple. C'est possible? – Gokul

+0

enable_if devrait fonctionner correctement. –

Répondre

2

enable_if est généralement utilisé pour discriminer entre différentes définitions d'une fonction. Dans un certain sens, c'est un moyen de surcharge plus puissant.

Il semble que vous essayez de permettre une fonction que si une condition est remplie, et donner une erreur de compilation autrement, puisque vous avez une définition unique de init. Si c'est correct, vous pouvez regarder dans BOOST_STATIC_ASSERT (ou static_assert dans C++ 0x) à la place.

+0

Je l'ai clarifié dans le commentaire pour la réponse ci-dessus. Pouvez-vous aider? Merci. – Gokul

+0

Pourriez-vous expliquer ce que vous essayez de faire? Ma conjecture est que votre code 'init' ne fonctionne que lorsque' X' est l'un des 'CheckTypes', mais vous voulez être capable d'instancier' P' aussi avec d'autres types. Si c'est le cas, vous voudrez peut-être définir un second 'init' qui soit' disabled_if'd sur les types autres que CheckTypes, et ne fait rien. –

2

Une option consisterait à utiliser une assertion statique. Les fonctions membres des classes de modèles sont instanciées paresseusement, ce qui signifie que si elles ne sont jamais appelées, le code pour elles ne sera pas généré. Cela signifie que vous pouvez écrire la fonction comme d'habitude, en espérant qu'elle ne sera appelée que pour les instanciations de bool, int ou double, et ensuite pour insérer une assertion statique dans cette fonction qui vérifie que c'est bien le cas.

Si, d'autre part, vous ne pouvez pas faire cela parce que vous instanciez explicitement le modèle, une autre option pourrait être de fournir une spécialisation de modèle pour ces trois types qui inclut la fonction membre supplémentaire. Cela vous permettrait d'inclure ou d'exclure explicitement la fonction, bien qu'elle puisse nécessiter un codage supplémentaire. Alternativement, vous pourriez envisager de faire de cette fonction supplémentaire non une fonction membre de la classe, mais plutôt une fonction libre. Par exemple, au lieu d'avoir une fonction init qui existe juste pour ces trois cas, envisager de définir trois fonctions qui ressemblent à ceci:

void Init(P<int>& toInit); 
void Init(P<double>& toInit); 
void Init(P<bool>& toInit); 

De cette façon, le code qui pourrait ne pas compiler pour les types arbitraires ne sont pas dans la classe générale elle-même, mais est plutôt déployé dans ces fonctions. Vous pouvez ensuite implémenter ces trois fonctions en termes de fonction d'assistance qui est elle-même un modèle.

+0

Hmmm ... En fait, j'ai instancié cette classe explicitement, mais je n'appelle pas la fonction du tout. Pourtant, il signale une erreur de compilation. C'est MSVC 2010. Quelle pourrait être la raison ??? – Gokul

+1

L'instanciation explicite d'un modèle (c'est-à-dire l'écriture de quelque chose à l'effet de 'la classe de modèle P ;') instanciera avec empressement toutes les fonctions membres.Instancier implicitement le modèle (par exemple en déclarant une variable de type P ) ne devrait pas le faire. Y a-t-il une raison pour l'instanciation explicite? – templatetypedef

+0

Ouais !!! cela a été fait pour sauver le temps de compilation. Puisque ce module est inclus partout ... – Gokul

Questions connexes