2011-09-26 4 views
6

J'ai une classe de modèle avec un paramètre de modèle int et un modèle. Maintenant, je veux me spécialiser une fonction membre:Comment se spécialiser membre de la classe de modèle avec le paramètre de modèle de modèle

template <int I> class Default{}; 
template <int N = 0, template<int> class T = Default> struct Class 
{ 
    void member(); 
}; 

// member definition 
template <int N, template<int> class T> inline void Class<N, T>::member() {} 

// partial specialisation, yields compiler error 
template <template<int> class T> inline void Class<1, T>::member() {} 

Quelqu'un peut-il me dire si cela est possible et ce que je fais mal sur la dernière ligne?

EDIT: Je voudrais remercier tout le monde pour leur contribution. Comme j'ai aussi besoin d'une spécialisation pour certains T, j'ai opté contre la solution de contournement proposée par Nawaz et spécialisé toute la classe, car il n'y avait qu'une fonction membre et un membre de données de toute façon.

Répondre

6

Vous ne pouvez pas spécialiser partiellement une fonction membre unique, vous devrez le faire pour toute la classe.

template <int I> class Default{}; 
template <int N = 0, template<int> class T = Default> struct Class 
{ 
    void member(); 
}; 

// member definition 
template <int N, template<int> class T> inline void Class<N, T>::member() {} 

// partial specialization 
template <template<int> class T> struct Class<1, T> 
{ 
    void member() {} 
}; 
2

En C++, vous n'êtes pas autorisé à spécialiser partiellement une fonction; vous ne pouvez que partiellement spécialiser les classes et les structures. Je crois que cela s'applique également aux fonctions des membres.

2

Vérifiez cet article sur: http://www.gotw.ca/publications/mill17.htm

Il est assez petit, et a de bons exemples de code. Il expliquera le problème avec la spécialisation de fonction de modèle de patial et montrera d'autres manières autour d'elle.

3

Comme ce n'est pas autorisé, voici une solution de contournement:

template <int I> class Default{}; 

template <int N = 0, template<int> class T = Default> 
struct Class 
{ 
    void member() 
    { 
     worker(int2type<N>()); //forward the call 
    } 
private: 
    template<int N> struct int2type {}; 

    template<int M> 
    void worker(const int2type<M>&) //function template 
    { 
     //general for all N, where N != 1 
    } 
    void worker(const int2type<1>&) //overload 
    { 
     //specialization for N == 1 
    } 
}; 

L'idée est, lorsque N = 1, l'appel de fonction worker(int2type<N>()) résoudra à la deuxième fonction (la spécialisation), parce que nous sommes passer une instance du type int2type<1>. Sinon, la première, la fonction générale, sera résolue.

Questions connexes