Salut,
je voulais vous faire part d'une "étrangeté" rencontrée il y a peu.
Le titre pose le contexte, il s'agit de compiler, sous clang dans mon cas, une fonction template, et surtout une spécialisation template de cette fonction.
Voyons le cas simplifié, avec une mise en évidence sur un simple cout:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // MyClass.hpp class MyClass { public: template<class T> void Send(const T& _k); }; template<class T> void MyClass::Send(const T& _k) { std::cout<<"base template method"<<std::endl; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 // MyClass.cpp template<> void MyClass::Send(const Item& _k) { std::cout<<"specialization for Item"<<std::cout; }Et c'est là que les ennuis commencent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 // AnotherFile.cpp ... Item k; GetMyclass()->Send(k); ...
Sans optimisation, en debug classique, la spécialisation est correctement appelée.
Mais en Release/Master, optimisé, non ! Le linker ne tient pas compte de la spécialisation présente dans une autre unité de compilation.
Pour résoudre ça : forward declaration de spécialisation template.
Derrière ce nom barbare, une simple ligne template<> void MyClass::Send(const Item& _k); à placer dans le header.
Donc le fichier devient:
La spécialisation est à placer en dehors de la définition de la classe. Sinon vous serez victime d'un message d'erreur
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 // MyClass.hpp class MyClass { public: template<class T> void Send(const T& _k); }; template<class T> void MyClass::Send(const T& _k) { std::cout<<"base template method"<<std::endl; } template<> void MyClass::Send(const Item& _k);
Notez que vous pouvez aussi implémenter la spécialisation dans le header, ce qui corrige également le problème. Mais c'est pas toujours possible. Ni très propre amha.error : explicit specialization of 'Send' in class scope
C'était mes 2 centimes du jour, qui pourraient vous aussi vous sauver plusieurs heures/jours !
Partager