Bonjour.

J'ai constaté que les question forum C++ de la spécialisation des méthodes templates revenaient souvent et que, si l'article sur la spécialisation précise à la fin que les méthodes templates doivent être spécifiées à l'extérieur des classes(ce que beaucoup semblent louper), la question de la spécialisation partielle des méthodes templates de classes templates n'était par contre pas traitée.

Cet article (enfin la seconde partie) ne devrait plus être valide lorsque le C++11 sera intégré partout, mais bon en attendant ...:s

Voici donc un petit essai d'article à ce sujet; il pourrait éventuellement être divisé en deux articles au besoin...
Citation Envoyé par Comment spécialiser une méthode template
La méthode template d'une classe peut être spécialisée en dehors (et uniquement en dehors) de la classe comme illustré ci dessous:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
class A                 //Déclaration de la classe
{
    public:
    template<class U>
    void methode()      //Notre méthode template
    {
        std::cout<<"Cette methode est generique"<<std::endl;
    }
};
 
template <>
void A::methode<int>()  //Spécialisation de la méthode pour les int
{
    std::cout<<"Cette methode est specifique au type 'int'"<<std::endl;
}
Cependant, dans le cas d'une classe template, spécialiser la méthode sans spécialiser la classe (spécialisation partielle) n'est pas possible.
Ainsi, seule une spécialisation de la classe et de la méthode (comme ci-dessous) fonctionnera:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
template <class T>
class A                        //Déclaration d'une classe template
{
    public:
    template<class U>
    void methode()             //Notre méthode template
    {
        std::cout<<"Cette methode est generique"<<std::endl;
        std::cout<<"Sa Classe est generique"<<std::endl;
    }
};
 
template <> template <>
void A<double>::methode<int>() //Spécialisation de la classe ET de la méthode
{
    std::cout<<"Cette methode est specifique au type 'int'"<<std::endl;
    std::cout<<"Avec une classe specifique au type 'double'"<<std::endl;
}
Il est cependant tout à fait possible de contourner ce problème

Une solution est de créer une seconde classe contenant la méthode désirée et de spécialiser cette classe:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template <class T,class U>
class B                        //Declaration d'une seconde classe template B
{
    public:
    static void operator() ()  //Déclaration d'un membre non template
    {
        std::cout<<"Cette methode est generique"<<std::endl;
        std::cout<<"Sa Classe est generique"<<std::endl;
    }
};
 
template <class T>
class B<T,int>                 //Specialisation partielle de B
{
    public:
    void operator() ()
    {
         std::cout<<"Cette methode est specifique au type 'int'"<<std::endl;
         std::cout<<"Avec une classe Generique"<<std::endl;
    }
};
Il ne reste plus qu'a appeler B() depuis la méthode de A:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
template <class T>
struct A                       //Déclaration d'une classe template
{
    template <class U>
    void methode()             //Déclaration d'une méthode template
    { 
         B<T,U>();             //Appel de la méthode de U
     }
};
Le code compile et fonctionne a présent.
Voilà.

Merci de me dire ce que vous en pensez et les probables détails à modifier.

Cordialement