boost mpl, passer une fonction dans un placeholder - C++ - Programmation
Marsh Posté le 14-09-2008 à 11:15:19
Tu effectue la beta-reduction de ta lambda trop tôt.
Ca devrait marcher :
Code :
|
Marsh Posté le 14-09-2008 à 13:13:31
Ok, merci de ton aide.
Donc si je comprend bien, la première erreur était d'utiliser uniquement les mpl::apply qui laissent le compilo faire l'unification sur tous les placeholders d'un coup. Il fallait donc lors de la définition de twice, utiliser le apply1 pour spécifier qu'il doit d'abord faire l'unification sur la première variable en lui empêchant d'unifier la deuxième variable.
Par contre il y a un truc que je comprend toujours pas. Dans la définition de twice tu as utilisé le apply1 directement comme valeur qui va être utilisé par la métafonction:
Code :
|
Et pas la valeur de retour du apply1 comme on aurait fait dans une métafonction...
Code :
|
Je pense que je dois pas bien comprendre comment fonction le apply1, car je pensais que c'était juste le raccourcis d'écriture que j'avais vu dans la doc: (bon bien sur, il ne s'agissait pas le la véritable implémentation mais je pensais que cela était proche)
Code :
|
Et donc, ça me paraissait logique de l'utiliser comme ça. Une petite explication (ou une indication où chercher dans la doc) ne serai pas de refus.
merci
Marsh Posté le 14-09-2008 à 15:25:11
Amonchakai a écrit :
|
En gros oui. T'as jamais fait de LISP ou de ML en étant plus jeune car ca aide grandement dans ce cas
Ta fonction twice elle se type de la façon suivante :
Code :
|
Mais comme apply n'est ni plus ni moins que la meta-fonction effetuant un appel de fonction, ca te donne de suite la bonne forme :
Code :
|
En C++, on retrouve :
Code :
|
Amonchakai a écrit :
|
Au moment ou tu recupére le ::type d'une meta-fonction, tu déclenches son évaluation. Or apply _1 sur _2 sans remplacement ne veut rien dire.
Il faut conserver ton expression paresseuse jusqu'à la fin.
Amonchakai a écrit :
|
C'est bien ça. Mais la différence se trouve au niveau de la sémantique de la chose. Quand tu écris une meta-fonction avec de splaceholder, il faut arreter de voire des types C++ et raisonner en terme de fonction paresseuse.
Marsh Posté le 14-09-2008 à 18:25:31
Ok, j'ai compris. merci beaucoup
(En ce qui concerne les langages fonctionnels, j'ai juste fait un peu de Caml l'année dernière. Ca aide déjà un peu dans la manière de procéder...)
Marsh Posté le 13-09-2008 à 18:55:42
Bonjour,
Je cherche à faire les exercices proposés dans la doc de la mpl de boost. Et j'avoue avoir un problème avec le suivant :
Build a lambda expression that has functionality equivalent to twice. Hint: mpl::apply is a metafunction!
twice prenant deux paramètres f et x et calcule (f o f)(x)
Sans passer par une fonction anonyme on peux facilement faire ça :
Mon problème est sur la réalisation de la fonction lambda. Comme elle est anonyme je veux la mettre directement dans un boost apply comme ça:
le problème c'est j'ai l'impression que le compilo se perd dans les placeholders. Il me sort :
d:\libc++\boost_1_35_0\boost\mpl\aux_\preprocessed\plain\apply_wrap.hpp(48) : error C2039: 'boost::mpl::apply<F,T1>' : is not a member of 'boost::mpl::apply<F,T1>'
with
[
F=boost::add_pointer<boost::mpl::_>,
T1=int
]
and
[
F=boost::mpl::_1,
T1=boost::mpl::_2
]
d:\libc++\boost_1_35_0\boost\mpl\aux_\preprocessed\plain\apply.hpp(63) : see reference to class template instantiation 'boost::mpl::apply_wrap2<F,T1,T2>' being compiled
with
[
F=boost::mpl::apply<boost::mpl::_1,boost::mpl::_2>,
T1=boost::add_pointer<boost::mpl::_>,
T2=int
]
d:\libc++\boost_1_35_0\boost\mpl\aux_\preprocessed\plain\apply.hpp(71) : see reference to class template instantiation 'boost::mpl::apply2<F,T1,T2>' being compiled
with
[
F=boost::mpl::apply<boost::mpl::_1,boost::mpl::_2>,
T1=boost::add_pointer<boost::mpl::_>,
T2=int
]
d:\projets\visual studio 2005\projects\metaprog\metaprog\main.cpp(50) : see reference to class template instantiation 'boost::mpl::apply<F,T1,T2>' being compiled
with
[
F=boost::mpl::apply<boost::mpl::_1,boost::mpl::_2>,
T1=boost::add_pointer<boost::mpl::_>,
T2=int
]
j'ai l'impression qu'il arrive pas a bien tout remplacer, surtout que tout doit a priori se faire en deux étapes :
- le remplacement des _1 par les boost::add_pointer<_>
- le remplacement du reste par les int...
Et je pense donc que c'est là que se trouve le problème, il peut pas faire tout en une passe. Et donc du coup, je vois pas trop comment faire une fonction lambda qui dans ses paramètres prend la métafonction avec laquelle elle doit travailler...
Si vous avez une idée