Symbole externe non résolu sous Visual

Symbole externe non résolu sous Visual - C++ - Programmation

Marsh Posté le 02-07-2009 à 16:38:19    

Bonjour,
 
Je rencontre un problème à la compilation d'un projet en C++ écrit sous Microsoft visual Studio que je ne comprends pas.
De manière simplifiée, j'ai rédigé trois fichiers :
 
Article.h
 

Code :
  1. #ifndef _NR_H_
  2. #define _NR_H_
  3. namespace Article
  4. {
  5.  template<typename T>
  6.  T cube(T);
  7. }
  8. #endif _NR_H_


 
Article.cpp
 

Code :
  1. #include "Article.h"
  2. template<typename T>
  3. T Article::cube(T a)
  4. {
  5. return (a*a*a);
  6. };


 
et main.cpp
 
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. #include "Article.h"
  4. int main()
  5. {
  6. int tata = 5;
  7. cout << Article::cube(tata) << endl;
  8. system("pause" );
  9. }


 
 
La compilation se passe bien jusquà l'édition de lien qui renvoie le message :
 

Code :
  1. 1>main.obj : error LNK2019: symbole externe non résolu "int __cdecl Article::cube<int>(int)" (??$cube@H@Article@@YAHH@Z) référencé dans la fonction _main
  2. 1>C:\Users\NathanGe\Documents\Visual Studio 2005\Projects\Template\Test\Debug\Test.exe : fatal error LNK1120: 1 externes non résolus
  3. 1>Le journal de génération a été enregistré à l'emplacement "file://c:\Users\NathanGe\Documents\Visual Studio 2005\Projects\Template\Test\Test\Debug\BuildLog.htm"
  4. 1>Test - 2 erreur(s), 0 avertissement(s)
  5. ========== Génération : 0 a réussi, 1 a échoué, 0 mis à jour, 0 a été ignoré ==========


 
Sauriez-vous d'ou provient cette erreur ?
 
L'utilisation des templates me parait pourtant correcte, d'autant plus que le programme :
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. namespace Article
  4. {
  5.  template<typename T>
  6.  T cube(T);
  7. }
  8. template<typename T>
  9. T Article::cube(T a)
  10. {
  11. return (a*a*a);
  12. };
  13. int main()
  14. {
  15. int tata = 5;
  16. cout << Article::cube(tata) << endl;
  17. system("pause" );
  18. }


 
se compile et s'éxécute sans erreur !
 
Pourriez-vous me fournir une aide pour comprendre mon problème ?
 
Merci d'avance

Reply

Marsh Posté le 02-07-2009 à 16:38:19   

Reply

Marsh Posté le 02-07-2009 à 16:43:42    

le corps d'un template va dans un .hpp non dans un .cpp

Reply

Marsh Posté le 02-07-2009 à 16:47:45    

Je ne retrouve pas ce format dans les fichiers de Visual.
Suffit-il de simplement renommer les fichiers ?
 
Est-ce que ce simple problème d'extension peut expliquer mon problème de compilation ?

Reply

Marsh Posté le 02-07-2009 à 16:48:37    

Je viens de test le renommages des fichiers, sans succès.

Reply

Marsh Posté le 02-07-2009 à 16:51:04    

non ...

 

le code de ton tempalte doit etre dans son ficheir d'entete :

 
Code :
  1. #ifndef _NR_H_
  2. #define _NR_H_
  3. namespace Article
  4. {
  5.     template<typename T> T cube(T) { return a*a*a; };
  6. }
  7. #endif
 

et ton Article.cpp n'a pas a existé


Message édité par Joel F le 02-07-2009 à 16:51:34
Reply

Marsh Posté le 02-07-2009 à 16:55:12    

Ce que Joel veut dire c'est que la definition du template doit generalement (*) etre visible au point d'instantiation.  Une technique est de la mettre dans l'entete (que Joel a appele .hpp mais toi tu lui a donne .h comme extension, l'extension ne joue aucun role) directement.  Certains utilisent un .tpp inclu dans le .hpp (ou le .h) permettant de separer clairement l'implementation de l'interface.
 
(*) Faire une recherche sur "export template" pour les amateurs d'exceptions.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 02-07-2009 à 16:59:24    

OK, cela marche effectivement ;)
 
Par contre, je ne comprends pas pourquoi la précédente écriture n'est pas autorisée.
 
Notamment, si la méthode est bcp plus longue que celle de ce test (ce qui est mon cas), est-ce que je reste contraint de la définir dans le même fichier que Article.h ?

Reply

Marsh Posté le 02-07-2009 à 17:06:53    

Le probleme principal est qu'instancier un template genere du code.  Fait la recherche que j'ai conseille.  Allez, un lien parmi d'autres possible: http://www.bourguet.org/v2/cpplang/export.pdf
 


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 02-07-2009 à 18:06:33    

Ok, merci de ces précisions,
 
l'écriture de Article.h en :
 

Code :
  1. #ifndef _ART_
  2. #define _ART_
  3. namespace Article
  4. {
  5.  template<typename T>
  6.  T cube(T);
  7. };
  8. template<typename T>
  9. T Article::cube(T a)
  10. {
  11. return (a*a*a);
  12. };
  13. #endif _ART_


 
marche parfaitement, ce que je recherchais.
 
Encore merci de votre aide,
 
NathanGe


Message édité par NathanGe le 02-07-2009 à 18:07:34
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed