Fonction globale: symbole externe non résolu

Fonction globale: symbole externe non résolu - C++ - Programmation

Marsh Posté le 19-03-2010 à 21:10:10    

:hello:  
 
J'ai un fichier global.cpp qui contient cette fonction qui me permet de convertir n'importe quoi en string:

Code :
  1. #include "global.h"
  2. template<typename T>
  3. string to_string( const T & Value ){
  4.     ostringstream oss;
  5.     oss << Value;
  6.     return oss.str();
  7. }


 
le contenu du fichier global.h:
 

Code :
  1. #ifndef GLOBAL_H
  2. #define GLOBAL_H
  3. #include <iostream>
  4. #include <sstream>
  5. template<typename T>
  6. string to_string( const T & Value );
  7. #endif


 
Le problème est que, lorsque je compile, j'obtiens les erreurs de link suivantes:

Code :
  1. 1>Édition des liens en cours...
  2. 1>editeur.obj : error LNK2001: symbole externe non résolu "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl to_string<int>(int const & )" (??$to_string@H@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABH@Z)
  3. 1>editeur.obj : error LNK2001: symbole externe non résolu "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl to_string<unsigned int>(unsigned int const & )" (??$to_string@I@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABI@Z)
  4. 1>C:\test\Release\test.exe : fatal error LNK1120: 2 externes non résolus


 
Le truc est que, si je mets directement le code de la fonction to_string dans le .h, ça compile sans erreur... Y-a-t-il un moyen de garder le corps de la fonction dans le .cpp ? Le mettre dans le .h me semble un peu sale :/


Message édité par sue soeur debeat le 19-03-2010 à 21:11:40
Reply

Marsh Posté le 19-03-2010 à 21:10:10   

Reply

Marsh Posté le 19-03-2010 à 21:27:51    

C'est pourtant ce qu'il faut faire.


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

Marsh Posté le 19-03-2010 à 21:33:05    

les template vont dans les .h point :o

Reply

Marsh Posté le 19-03-2010 à 22:18:47    

Ah je savais pas ! Merci pour l'info  :)

Reply

Marsh Posté le 20-03-2010 à 12:33:44    

fait toi un global_impl.h dans lequel tu fourres tes définitions de template et tu fais #include "global_impl.h" à la fin de ton global.h c'est beau gosse de faire ça comme ça


---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.
Reply

Marsh Posté le 21-03-2010 à 19:00:25    

Citation :

les template vont dans les .h point


 
Pas terrible, ce genre de réponse.
Les templates vont dans les .h, pourquoi ? Qu'est-ce qu'un fichier .h a de particulier, sachant que le précompilateur se contente de copier bêtement les include comme des sacs de caractères ? Est-ce que ça marche encore si je donne à mon header une extension .hpp, ou -soyons fous- .cpp ?
 
Se contenter d'apprendre bêtement que les templates vont dans les .h, c'est passer à côté de la raison simple et logique qui fait que les choses sont ainsi.
 
Si les templates vont dans les .h, c'est simplement parce que les templates sont des morceaux de code que le compilateur va spécialiser en attribuant des valeurs aux paramètres de template selon les besoins, en inspectant le code qui les utilise. Sachant que le résultat de la compilation du code templaté dépend des paramètres de template, qui peuvent prendre une infinité de valeur (par exemple des classes pas encore écrites), il est impossible de compiler le code templaté d'un côté, puis de le linker ensuite. Il faut pouvoir générer le binaire à la demande, et donc avoir accès non pas seulement aux prototypes, mais aussi à l'implémentation. Sachant qu'en général les gens n'#includent pas l'implémentation mais seulement les headers, il faut mettre l'implémentation dans les headers pour que le compilateur ait toutes les infos nécessaires au moment de la compilation.
 
Donc pour résumer, sue soeur debeat, voilà ce que le compilateur essaie de faire quand tu veux compiler ton bout de code :
- il voit que tu utilises un template, il prend les paramètres de template que tu utilises (ou qu'il arrive à deviner), et il génère un bout de code "détemplaté" par substitution des paramètres. En l'occurence, la seule chose qu'il détemplate est ton prototype de fonction, car c'est la seule chose qui a été incluse par le préprocesseur. Là par exemple, il a généré deux prototypes, en effectuant les substitutions T=int, et T=unsigned int
- comme il n'a trouvé que des prototypes dans le code à compiler, il les utilise en espérant que le linker saura se débrouiller avec
- étant donné que rien n'utilise ton template dans global.cpp, il n'a probablement rien compilé et donc :
- Quand le linker essaie de trouver les symboles correspondant à tes appels de fonction, il n'en trouve aucun et laisse tomber.
 
 
Bon, j'espère que je ne suis pas trop loin de la vérité, je ne suis pas un expert C++, loin de là, mais quand je vois des règles du genre "les templates vont dans les .h" j'essaie de comprendre pourquoi, et je trouve les raisons d'être de ces règles bien plus instructives que les règles elles-mêmes, qui sinon semblent un peu sorties de nulle part et ne sont utiles que dans des cas bien particuliers.


---------------
Any sufficiently complex bug is indistinguishable from magic.
Reply

Marsh Posté le 21-03-2010 à 20:02:02    

merci de m'apprendre mon travail :o

Reply

Marsh Posté le 21-03-2010 à 20:05:13    

Tu es professeur de C++ ? :o

 

Tu devrais avoir honte  :o


Message édité par _iOn_ le 21-03-2010 à 20:08:09

---------------
Any sufficiently complex bug is indistinguishable from magic.
Reply

Marsh Posté le 21-03-2010 à 20:07:44    

ouais j'ai honte, je tremble devant ton ton vengeur et ton verbe accablant. Je vais de ce pas me pendre.  
 
Ca devient une loose infame par ici c'ets dramatique.

Reply

Marsh Posté le 21-03-2010 à 20:13:12    

Ouais apparemment t'es pas prof de second degré par contre :/


---------------
Any sufficiently complex bug is indistinguishable from magic.
Reply

Marsh Posté le 21-03-2010 à 20:13:12   

Reply

Marsh Posté le 21-03-2010 à 20:15:58    

va falloir voir à reviser la signification de :o :o

Reply

Sujets relatifs:

Leave a Replay

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