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

  FORUM HardWare.fr
  Programmation
  C++

  Meta-Programmation Template : une introduction ....

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Meta-Programmation Template : une introduction ....

n°470269
Joel F
Real men use unique_ptr
Posté le 28-07-2003 à 22:37:25  profilanswer
 

Bon voila, j'ai décidé d'un commun accord avec Taz de pondre quelques topics sur le C++ , le vrai, celui qui fera de vous un homme :D
 
Je vais entamer ici une série de post sur la métaprogrammation template.  
 
PRINCIPES :  
 
La metaprogramamtion template est un ensemble de technique utilisant les mécanismes du template pour générer du code optimisé, au moment de la compilation, induisant un gain de vitesse non négligeable à l'éxécution.  
 
Quel intéret ? Et bien, la possibilité d'écrire du code sécurisé et permettant facilement de générer des constantes, des boucles déroulées et plein d'autres astuches.
 
La grande idée c'est comme dit Taz : "Think you're a compiler" !
Comment ce code peut il etre reecrit afin de mettre en evidence tel ou tel comportement template ? Est-ce que ce problème n'est pas simplement resoluble par une grammaire ??
 
1. Rappels
 
Quelques faits (mé)connus des templates :
 
1. Les classes et fonction templates sont instanciées en place ne produisant pas ou peu d'appel de fonction.
Le code template est quasiment toujours déroulé par le compilateur, un inline automatique.
 
2. Les arguments des templates ne sont pas nécessairement des types. Un template peut recevoir des types entiers (char,short,int,bool) en paramétres :
 

Code :
  1. template<int V> struct Constante
  2. {
  3.   static const int value = V;
  4. }
  5. // affiche '17'.
  6. cout << Constante<17>::value << endl;

 
 
On peut aussi feinter pour utiliser ds double par exemple :
 

Code :
  1. template<class T,T V> struct Constante
  2. {
  3.   static const T value = V;
  4. }
  5. // affiche '17.3'.
  6. cout << Constante<double,17.3>::value << endl;


 
3. Une fonction template peut determiner automatiquement ces paramétres de type.
 

Code :
  1. template<class T> T max( const T& a, const T& b )
  2. {
  3.   return ( a<b ? b : a );
  4. }

 
 
A partir de la, que peut on faire ???
 
2. La factorielle
Considérons maintenant un code ou il est nécessaire d'utiliser de nombreuses factorielles.Disons, un calcul de développement limité. Etant des constantes, ce genre de valeur sont souvent  
stockés dans des enum ou pire des #define !!!
Nos chers templates reviennent à la rescousse :
 

Code :
  1. template<int V> struct factorielle
  2. {
  3.   enum { value=V*factorielle<V-1> };
  4. };
  5. template<> struct factorielle<0>
  6. {
  7.   enum { value=1 };
  8. };


 
Maintenant, nous voulons évaluez 11! :
 

Code :
  1. int fact_11 = factorielle<11>::value;


 
Ce code enclenche une série d'évaluation :
 

Code :
  1. int fact_11 = 11*factorielle<10>::value;
  2. int fact_11 = 11*10*factorielle<9>::value;
  3. ...
  4. int fact_11 = 11*10*9*...*2*1 = 39916800;


 
Evidemment l'ensemble de ce code est produit et évalué à la compilation.
 
3. La Boucle FOR
Considérons ce code :
 

Code :
  1. for(int i=0;i<100000;i++) tab[i] = 2*i+1;

 
 
Il va générer 100000 tests de bornes, retour et affectation.
On peut gagner un peu en écrivant quelques choses comme :
 

Code :
  1. for(int i=0;i<50000;i++)
  2. {
  3.   tab[2*i] = 2*(2*i)+1;
  4.   tab[2*i+1] = 2*(2*i+1)+1;
  5. }

 
On gagne 50000 tests/retour.
L'ultime abus serait de dérouler ENTIEREMENT cette boucle, éliminant ainsi tous test et sauts. Bon, les maso léve la main et vont coder ca a la main :sol:
 
Comment faire ?
On va utiliser un aspect un peu méconnu du template : le fait que son ou ses arguments ne sont pas forcement des types mais peuvent etre des entiers. Considérons cette fonction template :
 

Code :
  1. // fonction de base
  2. template<int N> void remplir( int* tab )
  3. {
  4.    tab[N] = 2*N+1;
  5.    remplir<N-1>(tab);
  6. }
  7. // fonction de terminaison
  8. template<> void remplir<0>( int* tab )
  9. {
  10.    tab[0] = 1;
  11. }

 
 
Si nous l'appellons ainsi :
 

Code :
  1. remplir<99>(tab);


 
Le code suivant est produit à la compilation :  

Code :
  1. tab[99] = 199;
  2. tab[98] = 197;
  3. tab[97] = 195;
  4. ...
  5. tab[2] = 5;
  6. tab[1] = 3;
  7. tab[0] = 1;


 
Gain de vitesse notable (proche du x2 ou du x3) mas evidemment perte sur la taille de l'executable.
Par contre , il faut faire gaffe au paramétres. g++ ne deplie les templates que sur 512 niveau. Une option permet d'augmenter cette valeur, mais le temps de compilation devient vite infâme.
Un projet perso utilise 2048 comme limite et prends plusieurs minutes sur une seule fonction   :ouch:  
 
4. Un Tri résolu à la compilation
Le tri à bulles est un des tris les plus simples à gérer. Néanmoins, pour des tableaux de grandes tailles,
bah c'est pas trop ça :/. Pourtant, sur des tableaux de petites tailles, il reste le plus intéressant à implanter :
 

Code :
  1. inline void swap(int& a, int& b)
  2. {
  3.     int temp = a;
  4.     a = b;
  5.     b = temp;
  6. }
  7. void sort(int* data, int N)
  8. {
  9.   for (int i = N - 1; i > 0; --i)
  10.   {
  11.      for (int j = 0; j < i; ++j)
  12.      {
  13.         if (data[j] > data[j+1]) swap(data[j], data[j+1]);
  14.      }
  15.   }
  16. }


 
Voila, c'est trés simple. On peut alors se dire, par exemple, de spécialiser
le tri à bulles pour des tableaux de trois éléments :
 

Code :
  1. void bubbleSort(int* data, int N)
  2. {
  3.   for (int j = 0; j < N - 1; ++j)
  4.   {
  5.     if (data[j] > data[j+1]) swap(data[j], data[j+1]);
  6.   }
  7.   if (N > 2) bubbleSort(data, N-1);
  8. }


 
Bon .... maintenant, si nous voulons produire un code équivalent pour une taille voulue, on ne va pas non plus réécrire ce code N fois pour chaque taille. La Meta-Programamtion template arrive à la rescousse. Voila une classe de Tri A Bulles basé sur l'algo ci-dessus :
 

Code :
  1. template<int N> struct IntBubbleSort
  2. {
  3.   static inline void sort(int* data)
  4.   {
  5.     IntBubbleSortLoop<N-1,0>::loop(data);
  6.     IntBubbleSort<N-1>::sort(data);
  7.   }
  8. };
  9. template<> struct IntBubbleSort<1>
  10. {
  11.   static inline void sort(int* data) {}
  12. };


 
L'appel suivant :
 

Code :
  1. IntBubbleSort<4>::sort( int* data);


 
va générer un code semblable à :
 

Code :
  1. IntBubbleSortLoop<3,0>::loop(data);
  2. IntBubbleSortLoop<2,0>::loop(data);
  3. IntBubbleSortLoop<1,0>::loop(data);


 
Bon que dois faire IntBubbleSortLoop<N,M>::loop() ???
Et bien, il va générer les divers tests sur les éléments :
 

Code :
  1. template<int I, int J>
  2. class IntBubbleSortLoop
  3. {
  4.   private:
  5.   enum { go = (J <= I-2) };
  6.   public:
  7.   static inline void loop(int* data)
  8.   {
  9.      IntSwap<J,J+1>::compareAndSwap(data);
  10.      IntBubbleSortLoop<go ? I : 0, go ? (J+1) : 0>::loop(data);
  11.   }
  12. };
  13. class IntBubbleSortLoop<0,0>
  14. {
  15.   public:
  16.   static inline void loop(int*) {}
  17. };


 
Rebelote, voila le code de notre tri :
 

Code :
  1. IntSwap<0,1>::compareAndSwap(data);
  2. IntSwap<1,2>::compareAndSwap(data);
  3. IntSwap<2,3>::compareAndSwap(data);
  4. IntSwap<0,1>::compareAndSwap(data);
  5. IntSwap<1,2>::compareAndSwap(data);
  6. IntSwap<0,1>::compareAndSwap(data);


 
On approche de la solution, il suffit de coder la méthode IntSwap<I,J>::compareAndSwap
qui va effectuer le tri :
 

Code :
  1. template<int I, int J> struct IntSwap
  2. {
  3.   static inline void compareAndSwap(int* data)
  4.   {
  5.     if (data[I] > data[J]) swap(data[I], data[J]);
  6.   }
  7. };


 
swap() n'a pas changé :
 

Code :
  1. inline void swap(int& a, int& b)
  2. {
  3.     int temp = a;
  4.     a = b;
  5.     b = temp;
  6. }


 
Au final , notre appel IntBubbleSort<4>::sort( int* data); devient :  
 

Code :
  1. if (data[0] > data[1]) swap(data[0], data[1]);
  2. if (data[1] > data[2]) swap(data[1], data[2]);
  3. if (data[2] > data[3]) swap(data[2], data[3]);
  4. if (data[0] > data[1]) swap(data[0], data[1]);
  5. if (data[1] > data[2]) swap(data[1], data[2]);
  6. if (data[0] > data[1]) swap(data[0], data[1]);


 
Il suffit alors de changer le paramétre template de IntBubbleSort pour générer des fonctions de tri de taille diverses.
 
Au niveau perf, le tri est 7 à 3 fois plus rapide pour des tableaux de taille inférieure à 10, et le gain se stabilise vers 1.6 pour des tableau plus grand. un gain non négligeable somme toute. On peut aussi rajouter des paramétres templates pour gérer le type des données triées, modifiées la fonction de comparaison par des foncteurs etc ...
 
 
Voila, quelques choses simples. Je posterais une petite explication sur d'autres techniques liées aux templates comme les traits, les expressions templates etc ...
 
 
EDIT : typos, erreur diverse :p


Message édité par Joel F le 29-07-2003 à 09:21:01
mood
Publicité
Posté le 28-07-2003 à 22:37:25  profilanswer
 

n°470272
gm_superst​ar
Appelez-moi Super
Posté le 28-07-2003 à 22:45:10  profilanswer
 

Bravo ! Et bravo pour les exemples concrets. Ça manque souvent quand on veut saisir l'intérêt des templates.
 
/me qui se remet au C++ difficilement :sweat:


Message édité par gm_superstar le 28-07-2003 à 22:45:49

---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
n°470275
schnapsman​n
Zaford Beeblefect
Posté le 28-07-2003 à 22:45:28  profilanswer
 

http://membres.lycos.fr/cybear/Forum/topicD.gif


Message édité par schnapsmann le 28-07-2003 à 22:47:56

---------------
From now on, you will speak only when spoken to, and the first and last words out of your filthy sewers will be "Sir!"
n°470280
Taz
bisounours-codeur
Posté le 28-07-2003 à 22:55:04  profilanswer
 

je me permet de rajouter 2/3 trucs et un exemple tres concret pour ceux qui veulent se faire les dents.
 
 
1) je ferais un topic sur le mot clef typename, pour le moment retenez en le même usage que class pour les templates
2) JoelF utilise des enums, moi des constantes, les 2 choix sont valides suivant l'utilisation
 
Comment déterminer au moment de la compilation si 2 types sont équivalents?
 

Code :
  1. template<typename T1, typename T2>
  2. struct SAME_TYPE
  3. {
  4.   static const bool RESULT=false;
  5. };
  6. template<typename T>
  7. struct SAME_TYPE<T, T>
  8. {
  9.   static const bool RESULT=true;
  10. };


 

Code :
  1. SAME_TYPE<int, char>::RESULT;


 
 
Maitenant, une petite réflexion: quand on construit des classes, ont les fait souvent reposer sur des classes d'implémentation dont elles heritent, pour séparer implémentation brutale et interface. Ce qu'on aimerait faire, c'est un classe qui en fonction de son paramètre template hérite de la base qui va bien. Le code sans plus attendre
 

Code :
  1. // template IF statement
  2. template <bool c, typename TRUE, typename FALSE>
  3. struct IF;
  4. template <typename TRUE, typename FALSE>
  5. struct IF <true, TRUE, FALSE>
  6. {
  7.   typedef TRUE RESULT;
  8. };
  9. template <typename TRUE, typename FALSE>
  10. struct IF <false, TRUE, FALSE>
  11. {
  12.   typedef FALSE RESULT;
  13. };
  14. #include <iostream>
  15. using namespace std;
  16. template<class T>
  17. struct BigBar
  18. {
  19.   T item;
  20.  
  21.   void say_hello() const
  22.   {
  23.     cout << "BigBar\n";
  24.   }
  25. };
  26. template<class T>
  27. struct SmallBar
  28. {
  29.   T item;
  30.  
  31.   void say_hello() const
  32.   {
  33.     cout << "SmallBar\n";
  34.   }
  35. };
  36. template<class T>
  37. class Foo :
  38. private IF < sizeof(T) <= sizeof(int),
  39.      SmallBar<T>,
  40.      BigBar<T>
  41.            > :: RESULT
  42.   {
  43.   public:
  44.     void operator()() const
  45.       {
  46. say_hello();
  47.       }
  48.   };
  49. int main()
  50. {
  51.   Foo<int>()();
  52.   Foo<char>()();
  53.   Foo<double>()();
  54. }


 
 
vous allez me dire: tout ça ne sert pas à grand chose. Voici un exemple tres concret: une classe qui implémente un tableau de taille fixe. En fonction de son occupation mémoire, il doit résider soit dans la pile soit dans le tas. On veut que les 2 implémentations soient compatibles, et que tout ce qui le peut soit optimiser (comme la permutation de 2 tableaux, tres rapides dans le cas de pointeur)
voilà la classe et un petit programme de test
http://dejean.benoit.free.fr/code/Array.hpp
http://dejean.benoit.free.fr/code/test_Array.cpp
 
c'est un petit exemple sans prétention, non exempt de bugs, testé sommairement, mais fonctionnel quand je m'en étais servis. compatible avec STL
 

n°470283
tchoupinet​te
Posté le 28-07-2003 à 22:59:02  profilanswer
 

C'est une super idée votre truc !! Bravo !!  :jap:  
 
Cela dit je n'ai pas trop envi de devenir un homme ... :whistle:


---------------
http://membres.lycos.fr/axelfa
n°470284
Taz
bisounours-codeur
Posté le 28-07-2003 à 23:00:16  profilanswer
 

Tchoupinette a écrit :

C'est une super idée votre truc !! Bravo !!  :jap:  
 
Cela dit je n'ai pas trop envi de devenir un homme ... :whistle:  

moi non plus

n°470290
Joel F
Real men use unique_ptr
Posté le 28-07-2003 à 23:03:02  profilanswer
 

Arf,  
 
"le C++, pour nous les hommes"
 
Ah ben non pas super le slogan  [:taimp]

n°470293
Taz
bisounours-codeur
Posté le 28-07-2003 à 23:05:04  profilanswer
 

petite précision: la métaprogrammation de template repose sur les mécanismes de spécialisation de template, donc je vous invite à travailler ça. ce qui explique que  
 

Code :
  1. template <bool c, typename TRUE, typename FALSE>
  2. struct IF;
  3. template <typename TRUE, typename FALSE>
  4. struct IF <true, TRUE, FALSE>
  5. {
  6.   typedef TRUE RESULT;
  7. };
  8. template <typename TRUE, typename FALSE>
  9. struct IF <false, TRUE, FALSE>
  10. {
  11.   typedef FALSE RESULT;
  12. };


 
équivaut à  
 

Code :
  1. template <bool c, typename TRUE, typename FALSE>
  2. struct IF
  3. {
  4.   typedef TRUE RESULT;
  5. };
  6. template <typename TRUE, typename FALSE>
  7. struct IF <false, TRUE, FALSE>
  8. {
  9.   typedef FALSE RESULT;
  10. };


 
et faites attention car les templates supportent aussi les paramètres par défaut!

n°470294
Joel F
Real men use unique_ptr
Posté le 28-07-2003 à 23:06:23  profilanswer
 

Il faut aussi savoir que certains compilateurs ne supportent pas toutes cs acrobaties ... gcc et cie sont en général bien fiable, mais certains autres le sont moins :/
 
@Taz : Et quand est il de la spécialisation PARTIELLE d'un tempalte ? J'ai toujours du mal avec ca ....

n°470296
Taz
bisounours-codeur
Posté le 28-07-2003 à 23:08:02  profilanswer
 

Joel F a écrit :

Il faut aussi savoir que certains compilateurs ne supportent pas toutes cs acrobaties ... gcc et cie sont en général bien fiable, mais certains autres le sont moins :/
 
@Taz : Et quand est il de la spécialisation PARTIELLE d'un tempalte ? J'ai toujours du mal avec ca ....

des que je trouve un peu de temps, je fais un topic sur les differents types de spécialisation

mood
Publicité
Posté le 28-07-2003 à 23:08:02  profilanswer
 

n°470441
SoWhatIn22
Posté le 29-07-2003 à 08:19:22  profilanswer
 

bonjour,
 
je me permet de rajouter ce lien, qui m'avait initier à ce type de programmation pour ceux qui veulent aller voir:
http://osl.iu.edu/~tveldhui/papers [...] a-art.html
 
Comme il est dit:
"This article first appeared in the May 1995 issue of C++ Report. It has been reprinted in the book "C++ Gems" edited by Stanley Lippman."

n°470444
skeye
Posté le 29-07-2003 à 08:29:00  profilanswer
 

flag!
Vous vous déchainez sur le C++ !!
:jap:

n°470451
polo021
Posté le 29-07-2003 à 08:40:55  profilanswer
 

skeye a écrit :

flag!
Vous vous déchainez sur le C++ !!
:jap:


 drapo [:texla]

n°470467
umag
deux yeux sinon rien
Posté le 29-07-2003 à 09:06:50  profilanswer
 

:hello: Bravo Joel, c'était très clair !
 
(même si moi non plus, je ne veux pas devenir un homme :lol:)

n°470471
gatorette
Posté le 29-07-2003 à 09:10:13  profilanswer
 

Très très intéressant ! C'est cependant le type de code que j'hésite à écrire parce que je n'y pense pas, que je n'ai pas suffisamment d'expérience pour savoir quand l'utiliser, et qui peut rapidement jouer des pièges si on ne connait pas bien son compilateur (je pense notamment à la limite du nombre de niveaux de récursion supporté par un compilateur).
Le fait de travailler sous Visual C++ 6.0 n'invite pas non plus à pousser beaucoup les expériences (j'ai déjà passé un peu de temps sur du code qui me semblait devoir marcher mais ne fonctionnait pas parce que Visual C++ 6.0 ne respecte pas bien le Koenig Lookup).
 
Continuez ce genre d'articles qui sont très intéressants ! J'en profite pour orienter vers les C++ Tips and Tricks qui contiennent plein d'infos intéressantes.
 
Par contre, je pense qu'il y a une erreur ici :

Joel F a écrit :


...

Code :
  1. // fonction de base
  2. template<int N> remplir( int* tab )
  3. {
  4.    tab[N] = 2*N+1;
  5.    remplir<N-1>(tab);
  6. }
  7. // fonction de terminaison
  8. template<int N> remplir( int* tab )
  9. {
  10.    tab[0] = 1;
  11. }


...


 
La fonction de terminaison est plutôt :

Code :
  1. template<0> remplir( int* tab )
  2. {
  3. // ...
  4. }


il me semble ?


---------------
each day I don't die is cheating
n°470484
Joel F
Real men use unique_ptr
Posté le 29-07-2003 à 09:17:30  profilanswer
 

Code :
  1. // fonction de terminaison  
  2. template<> remplir<0>( int* tab )
  3. {
  4.   tab[0] = 1;
  5. }

 
 
Plus precisement, il faut bien remplir l'indice 0 du tabelau ...
Je corrige asap

n°470486
umag
deux yeux sinon rien
Posté le 29-07-2003 à 09:19:05  profilanswer
 

Oui, et donne aussi un type à la fonction sinon ça ne va toujours pas marcher :
 

Code :
  1. // fonction de terminaison   
  2. template<> void remplir<0>( int* tab ) 
  3.    tab[0] = 1; 
  4. }


Message édité par umag le 29-07-2003 à 09:19:46
n°470503
Joel F
Real men use unique_ptr
Posté le 29-07-2003 à 09:31:10  profilanswer
 

Correction fait [:prosterne]

n°470823
gloop
Posté le 29-07-2003 à 12:57:23  profilanswer
 

je complète l'exemple de Taz sur le template If pour les compilateurs sans spécialisation partielle. C'est pas toujours possible de se passer de la spécialisation partielle, mais là c'est bon. A l'utilisation c'est pareil
 
 

Code :
  1. // Les deux types suivants "simulent" des template-typedef
  2. // Sélectionne toujours le premier type
  3. struct SelectFirstType
  4. {
  5.    template<typename Tp1, typename Tp2>
  6.    struct TypeSelector
  7.    {
  8.       typedef Tp1 Type;
  9.    };
  10. };
  11. // Sélectionne toujours le second type
  12. struct SelectSecondType
  13. {
  14.    template<typename Tp1, typename Tp2>
  15.    struct TypeSelector
  16.    {
  17.       typedef Tp2 Type;
  18.    };
  19. };
  20. // On choisit le premier sélecteur
  21. template<bool condition>
  22. struct SelectSelector
  23. {
  24.    typedef SelectFirstType Selector;
  25. };
  26. // Spécialisation pour false, en choisissant le second type
  27. template<>
  28. struct SelectSelector<false>
  29. {
  30.    typedef SelectSecondType Selector;
  31. };
  32. // Selecteur de type
  33. template<bool condition, typename Tp1, typename Tp2>
  34. struct If
  35. {
  36.    // On sélectionne le selecteur
  37.    typedef typename SelectSelector<condition>::Selector Selector;
  38.    // puis on l'utilise
  39.    typedef typename Selector::TypeSelector<Tp1, Tp2>::Type Type;
  40. };

n°475681
nraynaud
lol
Posté le 02-08-2003 à 03:45:37  profilanswer
 

détail technique : la "fonction de terminaison" s'appelle "le point fixe" (et n'est pas toujours une fonction comme montré dans le premier exemple).
Tiens d'ailleur ils disent quoi vos différents compilos si vous en mettez pas, il gueule a l'instanciation ou á la compilation du template, il pete la pile ou il s'est méfié avant ?


---------------
trainoo.com, c'est fini
n°475712
Taz
bisounours-codeur
Posté le 02-08-2003 à 11:44:28  profilanswer
 

le mien il pète apres m'avoir afficher un message pour chaque instanciation...

n°475723
schnapsman​n
Zaford Beeblefect
Posté le 02-08-2003 à 12:01:07  profilanswer
 

nraynaud a écrit :

détail technique : la "fonction de terminaison" s'appelle "le point fixe" (et n'est pas toujours une fonction comme montré dans le premier exemple).
Tiens d'ailleur ils disent quoi vos différents compilos si vous en mettez pas, il gueule a l'instanciation ou á la compilation du template, il pete la pile ou il s'est méfié avant ?


 
Je pense que même les meilleurs compilos c++ n'ont pas l'intelligence nécéssaire pour détecter ce genre de choses : ils se content d'un profondeur maximale de "templetisation" à ne pas dépasser.
 
J'ajouterais que ce genre de choses est assez difficile à détecter: dans le cas général, cela revient grosso modo a décider de la terminaison d'un programme, ce qui est un problème NP complet.

n°476129
nraynaud
lol
Posté le 03-08-2003 à 05:31:48  profilanswer
 

SchnapsMann a écrit :

J'ajouterais que ce genre de choses est assez difficile à détecter: dans le cas général, cela revient grosso modo a décider de la terminaison d'un programme, ce qui est un problème NP complet.

Non, justement, ce cas précis (absence de point fixe dans une expression récursive) est assez simple, il donne un joli _|_ (bottom) quand tu tentes d'inférer son type.
Ça peut parraître bizzare de tenter de typer un type, mais en réalité ça se fait courament dans certains domaines. En prenenant le langage des templates comme un langage de script qui te génère du code C amélioré, c'est assez facile de faire le lien avec le domaine fonctionel (réécriture de graphes et pattern-matching sur des valeurs).
 
edit : si un jour je me motive, je ferais la démo de programmes fonctionnels en template C++ et en caml.


Message édité par nraynaud le 03-08-2003 à 05:40:01
n°631211
glacote
Posté le 04-02-2004 à 16:06:33  profilanswer
 

schnapsmann a écrit :


 
Je pense que même les meilleurs compilos c++ n'ont pas l'intelligence nécéssaire pour détecter ce genre de choses : ils se content d'un profondeur maximale de "templetisation" à ne pas dépasser.
 
J'ajouterais que ce genre de choses est assez difficile à détecter: dans le cas général, cela revient grosso modo a décider de la terminaison d'un programme, ce qui est un problème NP complet.


J'aimerais bien. En vrai, c'est indécidable (mais c'est sans doute ce que tu voulais dire) ;)

n°679185
Taz
bisounours-codeur
Posté le 21-03-2004 à 12:25:42  profilanswer
 

supprimez ces 2 messages svp

n°679192
xiluoc
un pc pour les unirs ....
Posté le 21-03-2004 à 12:55:43  profilanswer
 

bon a quoi sert le struct alors ?
je pose une question maintenant si ma question est completement stupide ... j irais voir ailleur.

n°679193
Taz
bisounours-codeur
Posté le 21-03-2004 à 12:59:24  profilanswer
 

elle est stupide

n°679194
verdoux
And I'm still waiting
Posté le 21-03-2004 à 13:00:00  profilanswer
 

Le struct définit un type et un espage de nommage.

n°679196
xiluoc
un pc pour les unirs ....
Posté le 21-03-2004 à 13:08:00  profilanswer
 

je ne savais pas comment creer son namespace, j ai apris quelque chose. donc ma question netait pas inutile.
merci.

n°679201
Taz
bisounours-codeur
Posté le 21-03-2004 à 13:09:56  profilanswer
 

xiluoc a écrit :

je ne savais pas comment creer son namespace, j ai apris quelque chose. donc ma question netait pas inutile.
merci.  

les struct/class n'ont rien à voir avec les "namespace"
 
 
et en bon français, on dit pas "espace de nommage" on dit "référentiel lexical"

mood
Publicité
Posté le   profilanswer
 


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

  Meta-Programmation Template : une introduction ....

 

Sujets relatifs
debuter la programmation avec un logiciel gratuitaide pour programmation
Template et virtuelle pureProgrammation d'une carte I/O
Programmation en Java: question de la part d'un débutant...Spécialisation template & Pétage de plomb
Question aux developpeurs : limites de programmationAffectation template & héritage
Programmation Pocket PCprogrammation shell
Plus de sujets relatifs à : Meta-Programmation Template : une introduction ....


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