[C++] exemple didactique de template de template

exemple didactique de template de template [C++] - C++ - Programmation

Marsh Posté le 26-01-2005 à 22:44:48    

Je recherche un exemple de template de template qui soit parlant. Merci.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 26-01-2005 à 22:44:48   

Reply

Marsh Posté le 26-01-2005 à 23:09:29    

xterminhate a écrit :

Je recherche un exemple de template de template qui soit parlant. Merci.


 
salut,
une fonction membre template d'un classe template ?
 
Sans la spécialisation, un exemple (pas tres concret) :
http://forum.hardware.fr/hardwaref [...] 2547-1.htm
D'ailleurs si qqun peut me renseigenr d'avantage sur le sujet en lien, je suis preneur ...

Reply

Marsh Posté le 26-01-2005 à 23:10:54    

Quelque chose du genre :

Code :
  1. template< template< typename X > typename Y >
  2. f(){}


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 26-01-2005 à 23:19:21    

ça n'existe pas ...
tu veux faire quoi exactement ?

Reply

Marsh Posté le 26-01-2005 à 23:33:56    

Code :
  1. #include <typeinfo>
  2. #include <iostream>
  3. template<typename T, template<typename> class C>
  4. void demo(const C<T> & )
  5. {
  6.   std::cout << "T = " << typeid(T).name()
  7.     << "\t C = " << typeid(C<T> ).name()
  8.     << '\n';
  9. }
  10. #include <vector>
  11. int main()
  12. {
  13.   std::vector<int> vi;
  14.   demo(vi);
  15. }


 
un peu d'astuce : si ça passe pas en une seule fois, faut faire en 2

Reply

Marsh Posté le 26-01-2005 à 23:34:41    

Boaf, il suffit de faire 2 templates, et d'en passer l'un à l'autre. Un exemple de 3 templates imbriqués:

Code :
  1. std::vector<std::pair<int,std::string> >

.
 
Un exemple plus ou moins à moi:

Code :
  1. template <class TYPE>
  2. class Iterator
  3. {
  4.   public:
  5. typedef TYPE POINTED;
  6. virtual ~Iterator<TYPE>() {}
  7. virtual const TYPE * operator *()  = 0;
  8. virtual const Iterator<TYPE> & operator ++()  = 0;
  9. };
  10. template <class TYPE> // TYPE should be an Iterator
  11. class IteratorWrapper
  12. {
  13.   public:
  14. IteratorWrapper(TYPE * content) : target(content) { }
  15. ~IteratorWrapper() { delete target;}
  16. const typename TYPE::POINTED * operator *()
  17. {
  18.  if (target)
  19.   return target->operator *();
  20.  else
  21.   return NULL;
  22. }
  23. IteratorWrapper & operator ++()   { target->operator ++(); return *this; }
  24.   protected:
  25. TYPE * target;
  26. };


 
Ca permet à une classe de renvoyer un pointeur vers un itérateur (très pratique pour avoir des hiérarchies d'itérateurs). Et le client peut mettre ça dans un IteratorWrapper qui fonctionne tout comme un iterator mais qui gère automatiquement le déréférencement et le delete à la fin.


Message édité par Lam's le 26-01-2005 à 23:35:47
Reply

Marsh Posté le 26-01-2005 à 23:43:19    

euh, j'ai dus mal à saisir ta sauce. Déjà certaines signature d'opérateurs ne sont pas valides. Et tu mixes template et virtual. Et j'ai toujours pas compris le sens de ton machin. Mais cela n'a pas d'importance, ça n'en n'a sans doute aucun, vu qu'il vaudrait mieux pas s'amuser à faire une affecation : c'est un sinistre mélange d'iterator, smartpointer et une tentative désespérer de traits ... passons

Reply

Marsh Posté le 26-01-2005 à 23:48:03    

[:rofl]
 
(désolé [:cupra])


Message édité par WhatDe le 26-01-2005 à 23:48:27
Reply

Marsh Posté le 26-01-2005 à 23:49:23    

Taz a écrit :

euh, j'ai dus mal à saisir ta sauce. Déjà certaines signature d'opérateurs ne sont pas valides. Et tu mixes template et virtual. Et j'ai toujours pas compris le sens de ton machin. Mais cela n'a pas d'importance, ça n'en n'a sans doute aucun, vu qu'il vaudrait mieux pas s'amuser à faire une affecation : c'est un sinistre mélange d'iterator, smartpointer et une tentative désespérer de traits ... passons


Nan, c'est qu'il manque pas mal de trucs, et qu'il y pas mal de notions pas très catholiques derrière (c'est pour ça que certains const manquent). Et bien sûr, j'ai dégagé les constructeurs de recopie de l'exemple, etc.
 
L'utilité, c'est effectivement de "composer" tout ça pour avoir des binious qui retournent d'autres binious qui composent des binious, qui pointent vers des binious, le tout étant alloué et supprimé dynamiquement par des hiérarchies d'itérateurs.  
 
Sans parler du fait que le code devait passer sous Visual C++ 6 et gcc 2.97... :-/ Mais au final, ça marche nickel, et c'est en prod depuis un sacré paquet de temps.

Reply

Marsh Posté le 26-01-2005 à 23:54:35    

bekr

Reply

Marsh Posté le 26-01-2005 à 23:54:35   

Reply

Marsh Posté le 27-01-2005 à 06:35:10    

Taz a écrit :

euh, j'ai dus mal à saisir ta sauce. Déjà certaines signature d'opérateurs ne sont pas valides. Et tu mixes template et virtual. Et j'ai toujours pas compris le sens de ton machin. Mais cela n'a pas d'importance, ça n'en n'a sans doute aucun, vu qu'il vaudrait mieux pas s'amuser à faire une affecation : c'est un sinistre mélange d'iterator, smartpointer et une tentative désespérer de traits ... passons


 
Euh, j'ai du mal à saisir ta sauce. Déjà, la moitié de tes conjugaisons ne sont pas valides. Et tu mixes pluriel et singulier. Et tu mixes féminin et masculin. Et je n'ai toujours pas compris le sens de ton machin. Mais cela n'a pas d'importance, ça n'en a sans doute aucune, vu qu'il ne vaudrait mieux pas s'amuser à t'apprendre une langue durant vingt ans: c'est un sinistre mélange d'anglais, de fautes en tous genres et une tentative désespérée d'expression en français... passons.

Reply

Marsh Posté le 27-01-2005 à 18:48:51    

Taz a écrit :

Code :
  1. #include <typeinfo>
  2. #include <iostream>
  3. template<typename T, template<typename> class C>
  4. void demo(const C<T> & )
  5. {
  6.   std::cout << "T = " << typeid(T).name()
  7.     << "\t C = " << typeid(C<T> ).name()
  8.     << '\n';
  9. }
  10. #include <vector>
  11. int main()
  12. {
  13.   std::vector<int> vi;
  14.   demo(vi);
  15. }


 
un peu d'astuce : si ça passe pas en une seule fois, faut faire en 2


 
Ok, merci. Si je comprends bien, le template de template sert principalement à la manipulation de conteneurs std.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 27-01-2005 à 18:58:51    

oui et non : les conteneurs standard sont une application commune. Si ton paramètre template est simplement "template<typename> class C" tu exprimes le fais que l'argument doit être un template lui aussi

Reply

Marsh Posté le 27-01-2005 à 19:00:47    

Bien, c'est clair.
 
Un détail concernant ton exemple. Pourquoi ne pas rappeler typename ->T<- dans le template imbriqué ? Perdre en flexibilité, gagner en sécurité...


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 27-01-2005 à 19:02:18    

essaie

Reply

Marsh Posté le 27-01-2005 à 19:09:42    

C'est à dire que le compilateur se débrouille comme un grand on dirait. Le rappel de T n'apporte rien dans ce contexte.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 27-01-2005 à 19:11:29    

oula. c'est l'usage et non la déclaration qui compte. De plus tu peux constater que les paramètres template template ne sont utilisable que dans la déclaration

Reply

Marsh Posté le 27-01-2005 à 19:14:16    

Ok, parfait.


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 27-01-2005 à 21:10:07    

A la place des modeles comme parametre de modele (au lieu du combo template template ...), on peut faire un autre choix, que l'on retrouve plus souvent :
 

Code :
  1. #include <vector>
  2. #include <list>
  3. using namespace std;
  4. template <class T,template<class> class V = vector>
  5. class Foo
  6. {
  7.     V<T> vt;
  8. };
  9. //ou  
  10. template <class T,class V = vector<T> >
  11. class Bar
  12. {
  13.     V v;
  14. };
  15. int main()
  16. {
  17.     Foo<int,list> fi;
  18.     Bar<int,list<int> > bi;
  19.     Bar<int,list<double> > bad; // :o
  20. }


 
Foo permet d'eviter la déclaration "bad".
Foo restreint le deuxieme parametre à etre un modele, ce que ne contraint pas Bar.
Avec Bar, on peut donc faire :
Bar<int,Mylistint> b;
Si on suppose que Mylistint est un type concret, et qu'il s'occupe du type int.

Reply

Marsh Posté le 27-01-2005 à 22:32:47    

Ce problème ne semble pas se rencontrer avec les fonctions génériques (exemple de taz) puisque c'est le compilo qui résoud les paramètre de type automatiquement.


---------------
Cordialement, Xterm-in'Hate...
Reply

Sujets relatifs:

Leave a Replay

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