Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1268 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Spécialisation template & Pétage de plomb

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Spécialisation template & Pétage de plomb

n°449018
Willyzekid
Posté le 04-07-2003 à 19:31:55  profilanswer
 

Sous VC++ (.NET)
Quelqu'un peut m'expliquer pourquoi 1. marche et 2. me renvoie ma préférée LNK2005?? (les déf + déclarations dans un même fichier)
 
1. Sans LNK2005

Code :
  1. template< class T>
  2. class IndexFile : public FileManager {
  3. /* blahblah */
  4. private:
  5.     bool extractIndex(unsigned long indexToExtract) {
  6.          /* blahblah */
  7.     }
  8. };
  9. template<>
  10. bool IndexFile<char>::extractIndex(unsigned long indexToExtract) {
  11.     /* blahblah spécialisé pour les char*/
  12. }


 
2. Avec LNK2005

Code :
  1. template< class T>
  2. class IndexFile : public FileManager {
  3. /* blahblah */
  4. private:
  5.     bool extractIndex(unsigned long indexToExtract);
  6. };
  7. template<class T>
  8. bool IndexFile<T>::extractIndex(unsigned long indexToExtract) {
  9.     /* blahblah */
  10. }
  11. template<>
  12. bool IndexFile<char>::extractIndex(unsigned long indexToExtract) {
  13.     /* blahblah spécialisé pour les char*/
  14. }


 
Une idée?? Parce que ca commence a me prendre le choux!!


Message édité par Willyzekid le 04-07-2003 à 20:43:22

---------------
Horizon pas Net, reste à la buvette!!
mood
Publicité
Posté le 04-07-2003 à 19:31:55  profilanswer
 

n°449322
LeGreg
Posté le 05-07-2003 à 02:33:13  profilanswer
 

tu veux la version longue ou courte?
 
version courte:
rajoute inline devant extractIndex
(par exemple)
 
LeGreg

n°450667
Willyzekid
Posté le 07-07-2003 à 23:52:08  profilanswer
 

Ben avec la version longue ca serait pas mal non plus :D (je rentre tout juste de week-end)
 
Pourquoi je dois la faire inline cette fonction, ca m'echappe? (d'autant plus qu'elle est un peu longue!) Pourquoi diable quand on spécialise un template, la spécialisation doit-elle être inline?


---------------
Horizon pas Net, reste à la buvette!!
n°450673
DJ_Mulder
Posté le 08-07-2003 à 00:42:45  profilanswer
 

Willyzekid a écrit :


Pourquoi je dois la faire inline cette fonction, ca m'echappe? (d'autant plus qu'elle est un peu longue!) Pourquoi diable quand on spécialise un template, la spécialisation doit-elle être inline?


 
Aucun compilateur c++ (enfin ceux que je connais, ie g++-3.2 et celui de visual .net) n'est capable de separer la declaration et la definition d'une classe en template.

n°450687
Willyzekid
Posté le 08-07-2003 à 01:43:46  profilanswer
 

DJ_Mulder a écrit :


 
Aucun compilateur c++ (enfin ceux que je connais, ie g++-3.2 et celui de visual .net) n'est capable de separer la declaration et la definition d'une classe en template.
 


 
Merci, ca, j'avais remarqué... :)

Citation :

(les déf + déclarations dans un même fichier)


 
Cela dit, ca n'a pas grand chose a voir avec inline. C'est pas parce que c'est dans le même fichier (décla + def) que c'est nécessairement inline. C'est une condition nécessaire mais pas suffisante.


---------------
Horizon pas Net, reste à la buvette!!
n°450711
gnoof
Posté le 08-07-2003 à 07:41:37  profilanswer
 

Le code template est réellement compilé lorsqu'une class template particulière est crée donc le compilo à besoin d'avoir acces à tous le code, il ne compilera pas le code qu'il ne voit pas, d'où l'erreur de link.
Si tu veux séparer la définition et la déclaration pour ton template tu dois inclure le deuxième fichier dans le premier.
 
montemplate.h:
template <class T> montemplate
{
};
 
#include "montemplate.cpp"

n°450720
kadreg
profil: Utilisateur
Posté le 08-07-2003 à 08:33:09  profilanswer
 

gnoof a écrit :

Le code template est réellement compilé lorsqu'une class template particulière est crée donc le compilo à besoin d'avoir acces à tous le code, il ne compilera pas le code qu'il ne voit pas, d'où l'erreur de link.
Si tu veux séparer la définition et la déclaration pour ton template tu dois inclure le deuxième fichier dans le premier.
 
montemplate.h:
template <class T> montemplate
{
};
 
#include "montemplate.cpp"
 


 
A noter que tous les compilateurs n'ont pas ce type de problème, et que certains arrivent à compiler des templates défini en fichiers séparés.


---------------
brisez les rêves des gens, il en restera toujours quelque chose...  -- laissez moi troller sur discu !
n°450762
farib
Posté le 08-07-2003 à 09:47:37  profilanswer
 

je croyais qu'aucun compilateur ne gérait le mot-clef export ?

n°450831
LeGreg
Posté le 08-07-2003 à 10:36:14  profilanswer
 

Citation :

Ben avec la version longue ca serait pas mal non plus


 
Cela vient de la maniere dont fonctionnent les compilateurs C.
 
Le C (et donc le C++) autorisent la programmation modulaire en fichiers .cpp séparés (qui constituent après le passage du préprocesseur, la translation unit). Ces fichiers séparés sont réunis à l'édition des liens.
Le probleme c'est que dans la définition du C initial, il ne peut y avoir deux fois le meme symbole défini dans plusieurs unités de traduction sinon il y a collision (LNK2005).
 
Comment faire donc? il faut que le corps de la fonction n'existe que dans un seul .cpp et soit occulté dans les autres. Les translation unit qui ont l'utilité de cette fonction se chargeront d'inclure le prototype de la fonction (comme une déclaration de fonction mais sans le corps), ou de s'appuyer sur le prototypage automatique (qui ne fonctionne qu'en C, a cause de la décoration des noms et la surcharge en C++).
 
Oui mais pour les fonctions inline ? Les fonctions inline sont un apport ultérieur du C++ qui a ensuite été intégré au C, et celles-ci requièrent que le corps de la fonction soit présent dans la translation unit courante pour que la fonction soit inlinable. Comme cela contredit la règle précédente, les fonctions inline sont donc la seule exception à la règle qui veut qu'il n'y ait qu'un seul corps de la fonction dans toutes les translation units. (je ne parle pas des templates qui n'existent vraiment qu'une fois instanciés).
 
Maintenant quid des classes ?
On peut avoir dans un fichier .h des définitions de classes et à l'intérieur de la définition, la définition complète de la méthode (body entre crochets).
Est-ce que cela ne contredit pas la règle ci dessus ?
Non, tout simplement parce que par défaut une méthode qui est entièrement défini dans le corps de la classe est inline par défaut (ce qui ne veut pas dire qu'elle soit inlinable et encore moins inlinée) mais ce qui veut dire que cela ne fera pas hurler l'éditeur de lien.
 
Par contre si tu ne fais que mettre le prototype de la méthode dans le corps de la classe et que tu mets le corps de la méthode en dehors des crochets de la classe sans préciser explicitement que le méthode est inline, alors la méthode n'est pas inline, et n'est donc pas soumise à l'exception des fonctions inlines.
 
Récapitulons:
 

Code :
  1. template<typename T> class toto {
  2.   void mafonction1() {}; // est inline
  3.   inline void mafonction2 (); // est inline
  4.   void mafonction3(); // n'est pas inline
  5. };
  6. template<typename T> void toto<T>::mafonction2()
  7. {
  8. }
  9. template<typename T> void toto<T>::mafonction3()
  10. {
  11. }


 
Et en l'absence du mot clé export, mafonction3() est impossible à mettre en oeuvre :/ .
 
Pour les compilateurs qui mettent en oeuvre export:
Comeau computing
(et oui c'est un peu tarabiscoté)
 
LeGreg

n°451420
Willyzekid
Posté le 08-07-2003 à 17:35:06  profilanswer
 

Merci beaucoup LeGreg (!), gnoof et les autres, vos explications sont claires et limpides!
 
Cela dit, mon problème est trés spécifique. Les templates, je sais les définir que ce soit en fichié séparé ou non. Mon problème n'est pas là!
 
Mon problème porte sur la SPECIALISATION d'un template (c'est pourtant marqué dans le titre :)). Cette fois, puisqu'apparement j'étais pas clair, je vais donner beaucoup plus de détail.
 
1. Pour la clareté de la démonstration, tout les bouts de code suivant, même si, dans la réalité, ils sont éclatés en fichiers séparés ont été regroupé (et testé tel quel) dans un même fichier. Les mêmes erreurs sont produites.
 
2. Le cas classique. C'est le même que celui de mafonction3() de LeGreg à la différence qu'il compile parfaitement, sans erreur de compil. Et en fait, c'est là que je comprends plus LeGreg: son code compile parfaitement malgré ce qu'il montre avant.
 

Code :
  1. template< class T>
  2. class IndexFile : public FileManager {
  3. public:
  4.    bool extractIndex(const unsigned long indexToExtract);
  5. };
  6. template< class T>
  7. bool IndexFile <T>::extractIndex(const unsigned long indexToExtract) {
  8.    /* blahblah */
  9. }


 
3. Une première spécialisation d'une fonction d'une classe template. Toujours pas d'erreur au link ce qui parait normal avec l'explication de LeGreg (ma fonction étant inliné par défaut, donc pas de problème au link)...même si on est dans le cas d'une spécialisation de template (donc une seule fonction instanciée)
 

Code :
  1. template< class T>
  2. class IndexFile : public FileManager {
  3. public:
  4.    bool extractIndex(unsigned long indexToExtract) {
  5.         /* blahblah */
  6.    }
  7. };
  8. template<>
  9. bool IndexFile<char>::extractIndex(unsigned long indexToExtract) {
  10.    /* blahblah spécialisé pour les char*/
  11. }

 
 
4. Et enfin, vient l'erreur...que je comprends toujours pas. Ma spécialisation de template ne passe pas. Alors que logiquement à l'instanciation d'une classe IndexFile<char>, seule la fonction IndexFile<char>::extractIndex(...) est créé, l'autre devant être ignoré. Et inversement pour une classe IndexFile< N_IMPORTE_QUOI>

Code :
  1. template< class T>
  2. class IndexFile : public FileManager {
  3. /* blahblah */
  4. private:
  5.    bool extractIndex(unsigned long indexToExtract);
  6. };
  7. template<class T>
  8. bool IndexFile<T>::extractIndex(unsigned long indexToExtract) {
  9.    /* blahblah */
  10. }
  11. template<>
  12. bool IndexFile<char>::extractIndex(unsigned long indexToExtract) {
  13.    /* blahblah spécialisé pour les char*/
  14. }


 
Bref, je m'en suis sorti autrement (via héritage).


Message édité par Willyzekid le 08-07-2003 à 17:36:38

---------------
Horizon pas Net, reste à la buvette!!
mood
Publicité
Posté le 08-07-2003 à 17:35:06  profilanswer
 

n°451432
Willyzekid
Posté le 08-07-2003 à 17:47:54  profilanswer
 

Un autre exemple pour appuyer ma démo. Je suis allé cherché dans un cours en ligne (Cours C/C++, Christian Casteyde).
 
Bien sûr, ce code compile à merveille, c'est à se taper la tête contre les murs.
 

Code :
  1. #include <iostream>
  2. using namespace std;
  3. template <class T>
  4. class Item
  5. {
  6.    T item;
  7. public:
  8.    Item(T);
  9.    void set(T);
  10.    T get(void) const;
  11.    void print(void) const;
  12. };
  13. template <class T>
  14. Item<T>::Item(T i) // Constructeur
  15. {
  16.    item = i;
  17. }
  18. // Accesseurs :
  19. template <class T>
  20. void Item<T>::set(T i)
  21. {
  22.    item = i;
  23. }
  24. template <class T>
  25. T Item<T>::get(void) const
  26. {
  27.    return item;
  28. }
  29. // Fonction d?affichage générique :
  30. template <class T>
  31. void Item<T>::print(void) const
  32. {
  33.    cout << item << endl;
  34. }
  35. // Fonction d?affichage spécialisée explicitement pour le type int *
  36. // et la méthode print :
  37. template <>
  38. void Item<int *>::print(void) const
  39. {
  40.    cout << *item << endl;
  41. }


---------------
Horizon pas Net, reste à la buvette!!

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Spécialisation template & Pétage de plomb

 

Sujets relatifs
Affectation template & héritageTemplate PHPLIB : Comment fonctionne les blocks ?
[blabla@hosto] Le topic des vieux[PHP] template engine : patTemplate
Attention ca va faire mal : template,inlining et AltiVec en autresun equivalent de HTML template en Java ...
[Resolu] [C++] template et Visual Studio 6.0HashMap.hash() ils ont pété un plomb ou quoi?
Template un peu finTemplate / Pointeur de fonction
Plus de sujets relatifs à : Spécialisation template & Pétage de plomb


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR