Bonjour à tous,

Je rencontre une erreur de link sur un point délicat de C++ sur un projet conséquent, et j'ai du mal à comprendre cette erreur.

J'ai réécrit un ECM qui reproduit le problème, constitué de 3 fichiers:
un fichier contenant le main(), et d'une bibliothèque statique mylib.a, construite à partir de mylib.h et mylib.cpp

le main:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
#include "mylib.hpp"
int main()
{
    std::cout << "hello world!\n";
    foo<int>();
    foo<float>();
    SomeFunc();
}
Le fichier d'en tete:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef MYLIB_HPP
#define MYLIB_HPP
 
#include <iostream>
 
template <typename T>
void foo()
{
    std::cout << "generic foo\n";
}
void SomeFunc();
#endif
Le code de mylib.cpp associé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
#include "mylib.hpp"
 
void SomeFunc()
{
    std::cout << "SomeFunc\n";
}
Jusque là, tout va bien... Je peux générer la bibliothèque statique, et compiler et exécuter le main().

Le problème apparaît quand j'essaie de spécialiser 'foo()': si j'ajoute dans le .h une spécialisation:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
template <>
void foo<int>()
{
    std::cout << " int foo\n";
}
Alors le linker me jette au motif d'une double définition de 'foo()', dans le main.cpp et dans mylib.cpp. Or, j'ai bien les "include-guards" !
Et pourquoi ce problème apparait-il uniquement en cas de spécialisation ? Cela voudrait dire que la fonction générique n'est pas instanciée dans mylib.a, mais que la spécialisation l'est!
Je ne comprend pas pourquoi, alors que la fonction n'est pas instanciée (?) dans mylib.a

Merci pour votre sagacité à résoudre ce mystère...