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; }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
// AnotherFile.cpp
...
Item k;
GetMyclass()->Send(k);
...
Et c'est là que les ennuis commencent.

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:
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);
La spécialisation est à placer en dehors de la définition de la classe. Sinon vous serez victime d'un message d'erreur
error : explicit specialization of 'Send' in class scope
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.

C'était mes 2 centimes du jour, qui pourraient vous aussi vous sauver plusieurs heures/jours !