Question sur les templates

Question sur les templates - C++ - Programmation

Marsh Posté le 12-01-2006 à 23:19:48    

Salut,
 
    Voila j'essaie de capter un peu le fonctionnement des template en C++ j'ai entendu dire que c'est le compilo qui genere une version du code pour chaque utilisation, ce qui est different des generics en Java ou c'est de la réécriture de code en compile time donc changement des <Type> par des casts et c'est tout ...
 
Je suis tombé sur un exemple d'un pote qui voulais gerer des plugins (des .o avec du code generique dedans) et ca marchait pas ... ptet parce qu'avoir des .o à partir des .h deja c'est mort.
Et que c'est mort de chez mort car deja les .o sont pas normalisés et que il n'existe aucun compilo qui face marcher le mot cle export.
 
Donc voila c'était pour qu'un esprit averti/avisé puisse m'éclairer au sujet des templates du C++, qu'en est t-il réelement, qu'est ce qui se passe derriere, en quoi c'est different de Java ?
 
PS : C'est quand meme ouf le retard sur la norme.

Message cité 1 fois
Message édité par Chronoklazm le 13-01-2006 à 02:20:18

---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 12-01-2006 à 23:19:48   

Reply

Marsh Posté le 13-01-2006 à 04:23:16    

Code :
  1. // THE QuiCK N' DIRTY TEMPLATE SURVIVAL KIT
  2. // oublies tout , le compilateur C++ moderne
  3. // il copie, il colle, il cherche, il remplace,ton code comme une dactylo déchainée
  4. // les templates ils te grondent si tu fais des bêtises
  5. // sinon ils font le travail de 50 ingénieurs allemands sous exta.
  6. // la définition canonique est assez simple
  7. template <class Noyau> struct Point
  8. {
  9. Noyau x,y,z;
  10. Point(Noyau _x=0,Noyau _y=0,Noyau _z=0):x(_x),y(_y),z(_z) {}
  11. };
  12. // l'instanciation aussi
  13. Point<double> origine;
  14. /* // qui remplace simplement "Noyau" par "double" et produit un imaginaire :
  15. struct __Point
  16. {
  17. double x,y,z;
  18. __Point(double _x=0,double _y=0,double _z=0):x(_x),y(_y),z(_z) {}
  19. };
  20. __Point origine; */
  21. // c'est déjà très pratique on peut écrire
  22. typedef Point<unsigned char> Couleur;
  23. const Couleur jaune(255,240,0);
  24. // après on peut très bien fournir des paramètres par défaut
  25. template <class Noyau=float> struct Point
  26. {
  27. Noyau x,y,z;
  28. Point(Noyau _x=0.0f,Noyau _y=0.0f,Noyau _z=0.0f):x(_x),y(_y),z(_z) {}
  29. };
  30. // qui permet des instanciations du genre
  31. Point<> bar;
  32. // les templates ne sont pas difficiles sur le nombre de paramètres et gèrent la précédence
  33. template <class Noyau=double,class Bool=bool,Bool checkBounds=true> struct Point
  34. {
  35. Noyau x,y,z;
  36. Point(Noyau _x=0.0f,Noyau _y=0.0f,Noyau _z=0.0f):x(_x),y(_y),z(_z)
  37. {
  38.  if(checkBounds)
  39.  {
  40.   /* etc */
  41.  }
  42. }
  43. };
  44. // les typedef prennent déjà une autre tournure...
  45. typedef Point<long double,bool,true> Point_Managed;
  46. typedef Point<float,size_t,false> Point_Savage;
  47. // ça reste un pré-processeur on peut très bien écrire
  48. template<int Major=0,int Minor=0,int Release=0,int Buid=-1> struct Version
  49. {
  50. void get(std::ostream&o)
  51.         {
  52.              o<<"v"<<Major<<'.'<<Minor<<'.'<<Release<<'.'<<Buid<<std::endl;
  53.         }
  54. };
  55. static Version<0,2> version;
  56. // aucun stockage superflu, ça marche récursivement aussi
  57. Point<Point<int> > bar;
  58. /* // qui correspond à peu près à ça
  59. struct __Point
  60. {
  61. struct  
  62. {
  63.     int x,y,z;
  64. } __Point_;
  65. __Point_ x,y,z;
  66. };
  67. __Point bar;
  68. */
  69. // les appels suivants sont ok
  70. bar.x.y=0;
  71. bar.z=Point<int>(7,-1,-1);
  72. // en fait le compilateur ne vérifie le code que quand c'est nécessaire, on peut écrire directement
  73.     template <class Objet,class Param> struct Executable
  74.     {
  75.         Objet o;
  76.        
  77.       //   Executable(const Objet&_o):o(_o){}
  78.              
  79.         void operator()(const Param &param1=-1)
  80.         {
  81.             o.Go(param1);
  82.         }
  83.     };
  84.    
  85.     // sans rien connaitre de Objet ou de Param, cepedant seules les classes avec une méthode Go (et les bons paramètres) seront acceptées si ton code appelle l'opérateur () de Executable
  86.    
  87.     struct Foo
  88.     {
  89.         void Go(std::string name)
  90.         {
  91.             std::cout<<"Foo::"<<name<<" fait son truc"<<std::endl;
  92.         }
  93.     };
  94.    
  95.     class Bar
  96.     {
  97.         // du blabla
  98.        
  99.         public :
  100.        
  101.            // ...
  102.    
  103.         void Go(int id)
  104.         {
  105.             std::cout<<"un Bar fait le truc n°"<<id<<std::endl;
  106.         }
  107.     };
  108.    
  109. // puis quelque part dans le code
  110.    
  111.     Executable<Foo,std::string> commande;
  112.    
  113.     // blablah
  114.    
  115.     commande("Hello" );
  116.    
  117.     // ou directement
  118.    
  119.     Executable<Bar,int>()(0x12345678);
  120. }
  121. // si les types sont connus à l'avance ça offre une alternative simple et efficace à l'héritage  
  122. // où tout est mis à plat avant l'exécution... tu dois maintenant comprendre ça :
  123. template<int count> class unrolled_loop
  124. {
  125.   public:
  126.     unrolled_loop()
  127.     {
  128.             unrolled_loop<count-1>();
  129.             std::cout <<"item #"<< count << std::endl;           
  130.     }
  131. };
  132. // ça prend tout son sens avec une spécialisation, la cerise sur le gâteau des templates :
  133. template <> class unrolled_loop<0>{};
  134. // ça arrête d'appeller récursivement le constructeur de unrolled_loop<count-1> pour le cas où count-1==0
  135. // à partir de la, il n'y a plus que les instructions std::cout <<"item #"... à ajouter au fichier objet/binaire.
  136. unrolled_loop<1024> scan_line; // 1024 tests & incréments économisés
  137. // yeah !!


Message édité par fra0 le 13-01-2006 à 06:44:29
Reply

Marsh Posté le 15-01-2006 à 23:27:52    

Chronoklazm a écrit :

Je suis tombé sur un exemple d'un pote qui voulais gerer des plugins (des .o avec du code generique dedans) et ca marchait pas ... ptet parce qu'avoir des .o à partir des .h deja c'est mort.
Et que c'est mort de chez mort car deja les .o sont pas normalisés et que il n'existe aucun compilo qui face marcher le mot cle export.


 
les .o ne sont pas normalisé, mais c'est pour ça que c'est mort. Et il y a des compilos qui implémentent export : ceux qui utilise le front end d'EDG et un ou deux autres il me semble, mais je ne sais plus lesquels. Je me rappelle l'avoir lu sur fclc++, dans un post de jean marc Bourguet.
 

Chronoklazm a écrit :

Donc voila c'était pour qu'un esprit averti/avisé puisse m'éclairer au sujet des templates du C++, qu'en est t-il réelement, qu'est ce qui se passe derriere, en quoi c'est different de Java ?


Pose une question un peu plus précise si tu peux, tu veux savoir comment fonctionne l'instanciation ?, comment on les utilisent ?, quels sont les différents modèles d'intanciation ?  
 

Chronoklazm a écrit :

PS : C'est quand meme ouf le retard sur la norme.


ça énerve pas mal de monde ...

Reply

Sujets relatifs:

Leave a Replay

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