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.
Partager