IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

type de retour de std::bind


Sujet :

C++

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut type de retour de std::bind
    Bonjour à tous, suite à la lecture de ceci

    Evite comme la peste les membres et structures dont le noms est préfixé par l'underscore " _ " (ou le double underscore " __ " ).

    Il s'agit de termes propres à l'implémentation que tu utilise, et il n'est pas du tout impossible qu'ils n'existent simplement pas si tu vient à changer de compilateur, voire, simplement, de version de la bibliothèque que tu utilise.
    J'ai donc un petit problème avec std::bind. J'utilise des choses réservées à l'implémentation pour déterminer le type de retour de std::bind.
    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    typedef std::_Maybe_wrap_member_pointer<Fc> __maybe_type;
    typedef typename __maybe_type::type __functor_type;
    typedef std::_Bind<__functor_type(Args...)> ResultFunctorType;
    Avec ResultFunctorType le type de retour.
    Comment puis-je avoir ce type de manière portable ?
    J'ai trouvé ce code dans functional de gcc4.5 Mingw après une recherche google non fructueuse.

    Merci à tous.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Tu peux utiliser auto(ou decltype) si ce n'est que pour avoir le type lors de l'appel à bind. Sinon il faut regarder du coté de std::function<>(ou boost::function<>, ou autres du meme genre)

  3. #3
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    +1 pour auto ici

  4. #4
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    J'utilise déjà auto, mais je dois ensuite repasser cette objet dans une classe template et donc lui donner le type de l'objet.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Quelque chose comme ceci ne te convient pas ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    auto maFonctionBindee = bind(maFonction, _1, 3);
    MaClasse<decltype(maFonctionBinde)> linstanceDeMaClasse;
    linstanceDeMaClasse.passerLaFonctionBindee(maFonctionBinde);

  6. #6
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Je dois dire que je ne dois pas comprendre comment decltype marche... mais je vais tester. Quelqu'un aurait un lien expliquant decltype ?

  7. #7
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    En fait, sa marche pas :

    J'ai une fonction appelant std::bind avec un tuple. La fonction va extraire le tuple et le passer à std::bind. Sauf que je dois mettre son type de retour que ne connait pas. Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<typename Fc,typename ...Args>
    struct Binding
    {
        typedef std::_Maybe_wrap_member_pointer<Fc> __maybe_type;
        typedef typename __maybe_type::type __functor_type;
        typedef std::_Bind<__functor_type(Args...)> ResultFunctorType;
     
        inline static ResultFunctorType MakeBindingObject(Fc Func, const std::tuple<Args...>& t);
    };
    Quelle solution proposez vous ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Je proposerais la plus simples meme si ce n'est pas la plus efficace, utiliser std::function<>.
    En fait je viens de me rapeller d'une utilisation légèrement spéciale de auto que je crois tu peux appliquer ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<class U, class V>
    auto maFonction(U const& u, V const& v) -> decltype(u+v);
    Je verrais ça avec une fonction publique et deux privé qui **itèrent** sur le tuple.

  9. #9
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Avec gcc, j'obtiens une erreur si je déclare MakeBindingObject comme
    auto MakeBindingObject(/*...*/)

    Voici l'erreur :

    error: 'MakeBindingObject' function uses 'auto' type specifier without late return type

  10. #10
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Oui, ca ne marche pas comme ca, il faut utiliser la syntaxe donné par Joe Dralliam :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<typename Fc,typename ...Args>
    struct Binding
    { 
      static auto MakeBindingObject(Fc Func, const std::tuple<Args...>& t)
    	  ->decltype(std::bind(Func,std::get<0>(t)))
      { return std::bind(Func,std::get<0>(t)); }
    };
    Par exemple (on peut utiliser [] à la place de auto aussi).

    (cf FaQ de Bjarne pour tout ce qui concerne auto et decltype)

  11. #11
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Bon je vais chercher pour auto et decltype, cependant, je ne vois pas comment faire sa dans mon cas.
    Je vous montre le code un peu plus complet :

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    namespace
    {
        template<unsigned int N, typename Fc, typename R, typename ...Args>
        struct ExtractTuple
        {
            template<typename ...Finis>
            inline static R Extract(Fc Func, const std::tuple<Args...>& t, Finis...Extracted)
            {
                return ExtractTuple<N-1, Fc, R, Args...>::Extract
                (static_cast<Fc>(Func), t, std::get<N-1>(t), Extracted...);
            }
        };
     
        template<typename Fc, typename R,  typename ...Args>
        struct ExtractTuple<0u, Fc,R,  Args...>
        {
            template<typename ...Finis>
            inline static R Extract(Fc Func, const std::tuple<Args...>&, Finis... Extracted)
            {
                return std::bind(Func, Extracted...);
            }
        };
     
        template<unsigned int N, typename R,typename Fc>
        struct ExtractFirst
        {
            template<typename ...Args>
            inline static R Extract(Fc Func, const std::tuple<Args...>& t)
            {
                return ExtractTuple<N-1, Fc, R,Args...>::Extract
                (static_cast<Fc>(Func), t, std::get<N-1>(t));
            }
        };
     
        template<typename R,typename Fc>
        struct ExtractFirst<0,R,Fc>
        {
            template<typename ...Args>
            inline static R Extract(Fc Func, const std::tuple<Args...>& )
            {
                return std::bind(Func);
            }
        };
    }
    template<typename Fc,typename ...Args>
    inline typename sf::GUI::Implementation::Binding<Fc,Args...>::ResultFunctorType sf::GUI::Implementation::Binding<Fc,Args...>::MakeBindingObject(Fc Func, const std::tuple<Args...>& t)
    {
        return ExtractFirst<sizeof...(Args), ResultFunctorType,Fc>::Extract(static_cast<Fc>(Func), t);
    }
    Si quelqu'un a une idée ...

  12. #12
    Invité
    Invité(e)
    Par défaut
    Ave ce code c'est très simple :

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
     
    namespace
    {
        template<unsigned int N, typename Fc, typename ...Args>
        struct ExtractTuple
        {
            template<typename ...Finis>
            inline static auto Extract(Fc Func, const std::tuple<Args...>& t, Finis...Extracted) -> decltype(ExtractTuple<N-1, Fc, Args...>::Extract       (static_cast<Fc>(Func), t, std::get<N-1>(t), Extracted...))
            {
                return ExtractTuple<N-1, Fc, Args...>::Extract
                (static_cast<Fc>(Func), t, std::get<N-1>(t), Extracted...);
            }
        };
     
        template<typename Fc,  typename ...Args>
        struct ExtractTuple<0u, Fc,  Args...>
        {
            template<typename ...Finis>
            inline static auto Extract(Fc Func, const std::tuple<Args...>&, Finis... Extracted) -> decltype(std::bind(Func, Extracted...))
            {
                return std::bind(Func, Extracted...);
            }
        };
     
        template<unsigned int N,typename Fc>
        struct ExtractFirst
        {
            template<typename ...Args>
            inline static auto Extract(Fc Func, const std::tuple<Args...>& t) -> decltype(ExtractTuple<N-1, Fc,Args...>::Extract(static_cast<Fc>(Func), t, std::get<N-1>(t)))
            {
                return ExtractTuple<N-1, Fc,Args...>::Extract(static_cast<Fc>(Func), t, std::get<N-1>(t));
            }
        };
     
        template<typename Fc>
        struct ExtractFirst<0,Fc>
        {
            template<typename ...Args>
            inline static auto Extract(Fc Func, const std::tuple<Args...>& ) -> decltype(std::bind(Func))
            {
                return std::bind(Func);
            }
        };
    }
     
     
    template<typename Fc,typename ...Args>
    inline auto sf::GUI::Implementation::Binding<Fc,Args...>::MakeBindingObject(Fc Func, const std::tuple<Args...>& t) -> decltype(ExtractFirst<sizeof...(Args),Fc>::Extract(static_cast<Fc>(Func), t))
    {
        return ExtractFirst<sizeof...(Args),Fc>::Extract(static_cast<Fc>(Func), t);
    }
    Pour cette utilisation d'auto tu peux aller voir par ici

    NB : Le code n'est pas testé, il peut manquer des parenthèses,point-virgule etc...

  13. #13
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Il faut donc mettre des auto partout... ok merci je test tout de suite.

  14. #14
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    En tout cas, petit problème :

    Comme vous voyez, j'utilise un espace de nom anonyme dans mon .inl
    Ceci cause comme problèmes que mon .hpp n'a aucune connaissance des classes ExtractFirst et autres.
    Cependant, il semblerait que je sois obligé de mettre le ->decltype() aussi dans le header (à moins que sa ne soit que dans le header). Comment faire ?

  15. #15
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    J'ai sortit tout sa du namespace anonyme, et j'obtiens plein de sorry,unimplemented avec gcc4.5

  16. #16
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    J'ai l'impression que GCC n'implement pas encore totalement bind, pas correctement du moins. Essay avec quelque chose comme bind1st à la place. Du coup plus de probème de retour car le type de retour de bind1st est bien définie.

  17. #17
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Je ne doute pas que sa marche avec bind1st, malheuresement, j'ai besoin de bind... il y a un autre moyen que auto et decltype pour faire ce que je veux ?

  18. #18
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Faut que tu changes de compilateur alors. Le problème ne vient pas de auto et decltype mais de bind, si tu veus en avoir le coeur net, tests :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int foo(int,int){return 0;}
     
    std::function<int (int, int)> f(&foo);
    auto f2 = std::bind(f,0);
    f2(0);
    Qui si je ne me trompe pas sur la lecture du draft devrait compiler sans problème (et compile avec bind1st), ne compile pas avec gcc.

  19. #19
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Je vais tester. Gcc 4.6 corrige ce bug ?

  20. #20
    Invité
    Invité(e)
    Par défaut
    Le problème ne vient pas std::bind(les memes erreurs apparaissent avec boost::bind) mais du mélange decltype/template variadiques....
    Et gcc 4.6 ne corrige pas le bug, malheureusement

Discussions similaires

  1. Perte de type en retour de fonction
    Par Bebel dans le forum Langage
    Réponses: 8
    Dernier message: 22/12/2005, 12h54
  2. Type de retour de la valeur d'une msgbox
    Par Aurèl90 dans le forum Access
    Réponses: 10
    Dernier message: 02/12/2005, 16h45
  3. [Oracle 9.1] Types de retour d'une fonction PL/SQL
    Par ftrifiro dans le forum PL/SQL
    Réponses: 8
    Dernier message: 12/10/2005, 16h54
  4. [type de retour pour un update]
    Par viny dans le forum PostgreSQL
    Réponses: 7
    Dernier message: 21/03/2005, 21h08
  5. [type de retour dans une proc]
    Par viny dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 19/03/2005, 14h35

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo