Boost MPL : déréférencer un itérateur

Boost MPL : déréférencer un itérateur - C++ - Programmation

Marsh Posté le 05-09-2008 à 20:39:32    

Bonjour,
   Depuis quelques temps j'essaye de me mettre à la MPL de boost. Ca fait mal à la tête mais c'est intéressant :D Je suis donc en train de faire les exercices qui sont proposé à la fin des tutoriaux de la doc. Et donc je suis sur le premier : vérifier qu'une séquence ne contiennent que des nombres égaux à 0 ou 1.
   Bon, j'y suis presque :
 

Code :
  1. typedef boost::mpl::vector_c<int, 0, 0, 1, 0, 2, 0> test_seq;
  2. struct Check {
  3.     template<typename PrevAns, typename CurrElm>
  4.     struct apply {
  5.         typedef typename boost::mpl::if_<
  6.             boost::mpl::or_<
  7.                 boost::is_same<CurrElm, boost::mpl::integral_c<int, 0> >,
  8.                 boost::is_same<CurrElm, boost::mpl::integral_c<int, 1> >
  9.             >,
  10.             PrevAns,
  11.             boost::mpl::next<PrevAns>
  12.         >::type type;
  13.     };
  14. };
  15. template<typename Seq>
  16. struct binary {
  17.     typedef typename boost::mpl::fold<
  18.         Seq,
  19.         boost::mpl::int_<0>,
  20.         Check
  21.     >::type type;
  22.     // BOOST_MPL_ASSERT_RELATION( type::value, ==, 0 ) ;
  23.     typedef typename boost::mpl::deref<type>::type derefType;
  24.     enum val {value = derefType::value };
  25. };
  26. int main(int argc, char **argv) {
  27.     std::cout<<binary<test_seq>::value;
  28.     return 0;
  29. }

 
 
mon problème, se trouve que je voulais compter le nombre d'éléments qui sont différents de 0 ou 1. Pour ça j'utilise le type que me retourne le fold. A chaque fois, je renvois le int_<> suivant du nombre précédent d'éléments trouvé.  
Le problème c'est que cela semble marcher qu'une seule fois. En effet, si il y a un seul nombre qui ne vérifie pas la condition ça marche. Mais par contre si j'en ai deux, j'ai une erreur de compil.
Le compilo m'annonçant

Citation :

'value' is not a member of "boost::mpl::next<mpl_::int_<0> >"


donc je sais pas trop, il a l'air de bloquer au moment du déréférençage de l'itérateur... Si vous avez une idée :)

Reply

Marsh Posté le 05-09-2008 à 20:39:32   

Reply

Marsh Posté le 05-09-2008 à 20:59:39    

Juste un petite remarque pour dire que je pense avoir bien compris, que quand je demande le suivant, j'obtiens un :

Citation :

next<next<...<next<int_<0> > ... > >

 
mon problème est donc a mon avis d'arriver a tout dépiler, c'est là que je pense que j'ai un souci...


Message édité par Amonchakai le 05-09-2008 à 21:00:25
Reply

Marsh Posté le 05-09-2008 à 22:12:36    

ah ok, j'ai vu :

 

change Check :

 
Code :
  1. struct Check
  2. {
  3.     template<typename PrevAns, typename CurrElm>
  4.     struct apply {
  5.         typedef typename boost::mpl::if_<
  6.             boost::mpl::or_<
  7.                 boost::is_same<CurrElm, boost::mpl::integral_c<int, 0> >,
  8.                 boost::is_same<CurrElm, boost::mpl::integral_c<int, 1> >
  9.             >,
  10.             PrevAns,
  11.             typename boost::mpl::next<PrevAns>::type
  12.         >::type type;
  13.     };
  14. };
 

Ton erreur viens du fait que tu renvoyait next<PrevAns> qui est une métafonction 0-aire et non une valeur type.


Message édité par Joel F le 05-09-2008 à 22:14:46
Reply

Marsh Posté le 05-09-2008 à 22:25:50    

Ton deref sert à rien, fold renvoit pas d'itérateur mais un type.
En outre, il est de bon aloi de forwarder les meta fonctions plutot que de les enfouir. binary s'ecrit plutot :
 

Code :
  1. template<typename Seq>
  2. struct binary : boost::mpl::fold<Seq,boost::mpl::int_<0>, Check>::type
  3. {};

Reply

Marsh Posté le 06-09-2008 à 09:32:48    

ok, j'ai compris.
Merci  :jap:

Reply

Marsh Posté le 11-09-2010 à 22:09:10    

je déterre
besoin d'une petite explication sur la technique du forward (héritage)
merci


---------------
.
Reply

Marsh Posté le 11-09-2010 à 22:21:41    

Pas sur de comprendre la question, mais [:drapal]  
 
j'attends aussi la réponse de l'expert

Reply

Marsh Posté le 11-09-2010 à 22:31:01    

(en C++ on parle plutôt de barbu que d'expert :D )


---------------
.
Reply

Marsh Posté le 11-09-2010 à 23:58:24    

forwarder la meta-function au lieu de l'appeler en interne fait gagenr qqs instanciations de templates et accélére la compil

Reply

Marsh Posté le 12-09-2010 à 11:03:51    

deux questions :
 
- le enum val initialement défini dans binary est fait dans mpl::fold  
- je ne comprends comment fonctionne le mécanisme initial avec State = int_<0> utile au premier appel


Message édité par Glock 17Pro le 12-09-2010 à 12:10:38

---------------
.
Reply

Marsh Posté le 12-09-2010 à 11:03:51   

Reply

Marsh Posté le 12-09-2010 à 13:34:08    

c'ets un fold comme en ML hein, State c'ets la valeur initiale du combinateur.

Reply

Marsh Posté le 12-09-2010 à 14:13:16    

ça change quoi si on mets int_<1> par exemple ou int_<3>


---------------
.
Reply

Marsh Posté le 12-09-2010 à 15:53:04    

autre question une idée d'où je pourrais trouver des exemples, présentés de manière accessibles, permettant de voir concrètement, comment et/ou dans quel cas MPL est utilisée.
le tuto de boost est trés bien mais ne permet pas de se rendre compte concrètement sur un petit exemple d'une utilisation pratique


Message édité par Glock 17Pro le 12-09-2010 à 16:03:05

---------------
.
Reply

Marsh Posté le 12-09-2010 à 16:40:19    

Glock 17Pro a écrit :

ça change quoi si on mets int_<1> par exemple ou int_<3>


 
fold State List Op fait la chsoe suivante
 
Op( State, Op( List(0), Op(List(1) , ... )) ) ) ) );
 
fold quoi: http://en.wikipedia.org/wiki/Fold_ [...] unction%29

Reply

Marsh Posté le 12-09-2010 à 16:42:10    

mais j'arrive pas à voir comment la valeur peut être conserver et transmise à l'itération suivante
 
apply défini un champ value ?


Message édité par Glock 17Pro le 12-09-2010 à 18:31:23

---------------
.
Reply

Marsh Posté le 12-09-2010 à 19:25:39    

non, elle passe le nouveau type dans les paramètres de l'appel suivant.
Tu sais pas ecrire de fonction stateless ?

Reply

Marsh Posté le 12-09-2010 à 20:15:35    

non je débute juste, ça m'a l'air énorme comme lib niveau concept à assimiler


---------------
.
Reply

Marsh Posté le 12-09-2010 à 21:21:27    

si t'as fait u MLou de l'Haskell avant, ca passe tout seul.

Reply

Marsh Posté le 12-09-2010 à 21:32:20    

hélas...mais bon ça s'apprend faut juste être prêt à y investir le temps nécessaire, dans du code applicatif ça peut avoir un intérêt ou clairement peu?


---------------
.
Reply

Marsh Posté le 12-09-2010 à 21:43:07    

ca sert à grandement simplifier l'implant de certaines interfaces.
C'est plus orienté dev. de library que applicatif brut.
 
Quoique les trucs genre units etc ca peut servir.

Reply

Marsh Posté le 12-09-2010 à 22:02:39    

a priori avec la meta-prog on manipule uniquement des types (ou des valeurs pour des optimisations maths)...ok mais j'ai un peu de mal à cerner   ce que l'on peut obtenir en manipulant des types


Message édité par Glock 17Pro le 13-09-2010 à 07:22:09

---------------
.
Reply

Marsh Posté le 13-09-2010 à 10:36:40    

Bah, ca permet aussi de générer des codes spécialisé sur des conditions non triviale

Reply

Marsh Posté le 14-09-2010 à 19:09:25    

oui je vois, ça ne révolutionne pas le monde mais ça reste pratique tout de même de pouvoir faire ça directement en C++


Message édité par Glock 17Pro le 14-09-2010 à 19:09:56

---------------
.
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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