2009-02-15 6 views
1

J'ai converti une fonction en modèle et j'ai commencé à recevoir cette erreur. Je ne dois pas comprendre une limitation des modèles. Quelqu'un peut-il me dire pourquoi cela est cassé?Erreur de lien à l'aide de modèles

Je reçois cette erreur:

Undefined symbols: 
    "bool foo<int>(int const&, int const&)", referenced from: 
     _main in file1.o 
ld: symbol(s) not found 

Lorsque je lie le code suivant. Le code est simplifié, mais échoue toujours. Le premier fichier contient:

#include <iostream> 
template <class T> bool foo (const T&, const T&); 

int main() 
{ 
    int left = 1; 
    int right = 2; 

    if (foo <int> (left, right)) 
    std::cout << "foo!" << std::endl; 

    return 0; 
} 

Et le second fichier contient:

template <class T> bool foo (const T& left, const T& right) 
{ 
    return true; 
} 

Répondre

3

Pour la raison que Uri a donné, les méthodes de modèle sont généralement définies dans le fichier d'en-tête. Parce que vôtre est une fonction et non une méthode d'une classe, définissez-la explicitement (dans le fichier d'en-tête qui peut être inclus par plus d'un fichier CPP) comme statique ou inline.

Mettez dans votre foo.h

template<class T> inline bool foo (const T& left, const T& right) 
{ 
    return true; 
} 

Mettez dans votre main.cpp

#include <iostream> 
#include "foo.h" 

int main() 
{ 
    int left = 1; 
    int right = 2; 

    if (foo <int> (left, right)) 
    std::cout << "foo!" << std::endl; 

    return 0; 
} 

Le code cpp voit maintenant toute la déclaration de la fonction de modèle.

D'autres solutions sont énumérées ici: How can I avoid linker errors with my template functions?

+0

mods statique/inline n'ont aucun effet. Je suis perplexe. –

+0

J'ai ajouté un exemple et un hyperlien à ma réponse. – ChrisW

+0

Merci pour le lien, je vois la syntaxe correcte est quelque chose comme modèle foo (...); Je ne me souviens pas de la syntaxe exacte pour le faire sans l'horrible fichier inline-in-an-h. – Uri

2

Cela fait des années que je l'ai fait beaucoup C++, mais je pense que vous rencontrez un problème de compilation séparée. Les modèles sont instanciés lors de la compilation, pas de liaison. Par conséquent, lorsque vous appelez foo(), vous instanciez réellement le modèle dans le sens où aucun nouveau code de fonction n'est généré, vous créez simplement un symbole que l'éditeur de liens doit résoudre.

Cependant, lorsque le second fichier est compilé, il ne contient que le modèle et il n'est jamais instancié, donc aucune version de foo() qui traite réellement ints n'est générée. Par conséquent, lorsque vous reliez tout ensemble, vous obtenez l'erreur. Je ne suis pas sûr à 100% quoi faire à ce sujet, mais je soupçonne que vous auriez besoin de forcer une instanciation de foo() avec ints dans ce second fichier (en supposant qu'il s'agit d'un C++). J'ai seulement travaillé avec des modèles de classe, pas des modèles de fonction, je suis sûr que quelqu'un vous donnera le code exact ...

Questions connexes