Template, oublirais-je quelque chose?
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:
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:
1 2 3 4 5
|
template <typename T1, typename T2>
class Derivee1;
template <typename T1>
class Derivee2; |
et deux tag simples
Code:
1 2 3
|
struct tag1{};
struct tag2{}; |
Si je définis Derivee1 sous la forme de
derivee1.h
Code:
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:
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:
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:
1 2 3 4 5 6 7 8
|
template<>
class Derivee2<tag2> : public Base{
public:
Derivee1(){}
void foo();
void bar();
}; |
derivee2_explicit.cpp
Code:
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 :question: