Salut,

Pour une fois, c'est moi qui vient avec un problème de template.
Soit une classe de base "classique" sous la forme de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
class Base{
    public:
        Base(){}
       /* interdisons la copie et l'affectation (C++11 inside) */
        Base(Base const &) = delete;
        Base & operator = (Base const&) = delete;
        /* défini dans le cpp, ne fait strictement rien */
        virtual ~Base(); 
        virtual void foo() = 0;
        virtual void bar() = 0;
};
A laquelle on rajoute deux classe template, l'une sous la forme de
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
template <typename T1, typename T2>
class Derivee1;
template <typename T1>
class Derivee2;
et deux tag simples
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
 
struct tag1{};
struct tag2{};
Si je définis Derivee1 sous la forme de
derivee1.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
template <typename T1, typename T2>
class Derivee1 : public Base{
    public:
        void foo();
        void bar();
};
je peux déporter la spécialisation (partielle ou totale) de foo dans un fichier d'instanciation explicit:
derivee_explicit.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
template <>
void Derivee1<tag1, tag2>::foo(){
    std::cout<<"ca marche";
}
template <>
void Derivee1<tag1, tag2>::bar(){
    std::cout<<"Si ca va pour l'un, ca va pour l'autre";
}
template class Derivee1<tag1, tag2>;
[EDIT]
Notez que cela fonctionne aussi très bien avec une spécialisation partielle : si je définissait template<typename T1> class Derivee1<T1,tag2>, ca marcherrait
[/EDIT]
Si je fournis directement une spécialisation totale sous une forme proche de
Derive2OK.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
template<>
class Derivee2<tag1> : public Base{
    public:
       Derivee2(){}
       void foo(){
           std::cout<<"ca marche";
       }
       void bar(){
            std::cout<<"Si ca va pour l'un, ca va pour l'autre";
       }
};
Par contre, si j'essaye de mixer les deux (spécialisation totale et export de la fonction)
Derivee2KO.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
template<>
class Derivee2<tag2> : public Base{
    public:
       Derivee1(){}
       void foo();
       void bar();
};
derivee2_explicit.cpp
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
template <>
void Derivee<tag2>::foo(){
    std::cout<<"Ben non, justement";
}
template <>
void Derivee1<tag2>::bar(){
    std::cout<<"Le compilateur ne trouve pas les prototypes";
}
template class Derivee2<tag2>;
Je dois avoir oublié quelque chose, mais quoi