Bonjour,
Avec la venu du mot clef auto, boost::result_of a t-il encore un intérêt ?
Merci
Bonjour,
Avec la venu du mot clef auto, boost::result_of a t-il encore un intérêt ?
Merci
Son utilisation première est de récupérer un type de retour d'un objet Fonction Polymorphe dans un contexte générique. Elle reste valide.
boost::result_of est de toute façon la même chose que std::result_of.
Alors que auto sert à obtenir le type d'une expression à partir de son initialisation.
Les deux outils n'ont pas le même objetif, l'un sert à déterminer un type de retour d'un foncteur (dans le sens le plus large), l'autre à simplifier la création d'objet (il arrive que déterminer le type soit complexe et long à écrire).
ok, d'ailleurs ça m'a fait découvrir un truc :
on passe infiné l'instance d'une classe et non uniquement un type à résult_of. j'étais persuadé que les paramètres template se limiter à des types mais pas à type et/ou intance d'une classe...
si je rajoute un consctuteur à G prenant un int, et que je le passe à F<G(3)> ça ne compile plus...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 struct G { bool operator() () const {std::cout<<"foo"<<"\n"; } }; template<typename Q> struct F{ typedef Q type; }; struct is_positive_number { bool operator()(int x) { return 0 < x; } }; int main() { typedef boost::result_of< is_positive_number() >::type result_type; F<G()>::type typer; typer(); //erreur linkage, de même que F<G()>:type() ne compile pas ?! std::cin.ignore(); return boost::exit_success; }
QUelqu'un aurait une précsion/explication concernant ce point?
Non, ca ne fonctionne pas comme ca. Pour comprendre voici à quoi pourrait ressembler result_of :
Les declval permettent de "faire semblant" de passer une variable du type indiqué en template, et decltype permet d'évaluer le type de l'expression entre paramètre, ici ca donne le type de retour du foncteur.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 template<class Fn, class... ArgTypes> struct result_of; template<class Fn, class... ArgTypes> struct result_of<Fn(ArgTypes...)> { typedef decltype(std::declval<Fn>()(std::declval<ArgTypes>()...)) type; };
Celui de boost date d'avant l'introduction de decltype et declval, il fonctionne différement, mais l'idée doit être la même. (regardes le code de boost si ca t'interesse)
Donc c'est bien des types que tu passes à result_of et pas des instances, c'est juste la syntaxe qui permet de faire ressemble (à part que c'est pas le type de retour mais le nom du foncteur) ca à des signatures de fonctions (et si tu mets pas de paramètres ca ressemble à une instanciation, mais ca n'en est pas).
Compile
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct A { int operator()(int) {return 1;} }; typedef result_of<A(int)>::type r; r i = r(); std::cout << i; //affiche 0
Ne compile pas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 struct A { int operator()(int) {return 1;} }; typedef result_of<A()>::type r; r i = r(); std::cout << i;
Les paramètres templates sont forcément des types (template au besoin), ou des entiers (size_t et void* assez courrant).
donc l'idée c'est qu'une signature de fonction c'est un type ? pourtant dans mon exempe c'est bien le nom d'une classe que je passe,... j'ai pas compris ton post, pour moi decltype c du c1X
EDIT:ah ou l'idée ce que le compilo voit une fonction retournant un type G et ne prenant aucun paramètre!!
Non, j'ai dit que ca ressemble à une signature de fonction (et oui le type d'une fonction c'est sa signature), sauf qu'à la place d'indiquer le type de retour (cest ce qu'on veut, on ne peut pas l'indiquer), on indique le nom du foncteur, dans ce cas le nom de la classe : G.
Oui, decltype c'est du C++1x, sauf que c'était juste pour te montrer à quoi pouvait ressembler reslut_of, boost fait autrement, mais ca doit être plus long.
C'est rien de le dire
result_of est une classe template qui prends un argument, et qui est spécialisé pour :
* les fonctions (de 0 a 9 arguments)
* les méthodes (de 0 à 9 arguments)
* les foncteurs (de 0 à 9 arguments)
* les classes qui héritent d'un foncteur classique (genre std::unary_function).
Le tout en utilisant SFINAE de manière régulière et rigolote si je me rappelle bien, en prenant en compte les différences de comportement des compilateurs vis à vis des spécialisation partielles.
C'est un plaisir à lire, comme code. Ca rends copain avec Visual Basic, pour tout dire.
[FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.
Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.
effectivement ça use à outrance boost preprocessor, faut s'accrocher
c'est normal que ce code me renvoit void (sauf si je rip)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 typedef boost::result_of<int()>::type var; //var est de type void
Partager