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

Boost C++ Discussion :

boost::in_place avec boost_bind.


Sujet :

Boost C++

  1. #1
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut boost::in_place avec boost_bind.
    Bonjour,
    Je souhaite un générateur un peu générique et je n'y arrive pas:
    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
    struct A
    {
       int m_1;
       int m_2;
       A(int P_1=0,int P_2=0):m_1(P_1),m_2(P_2){}
    };
    
    class B
    {
    public:
       B(const A&P_a):m_a(P_a)
       {}
    
    protected:
       A m_a;
    };
    
    template<class T, class InPlaceFactory>
    T Generer(InPlaceFactory const& aFactory)
    {
       char L_retour[sizeof(T)];
       aFactory.template apply<T>(L_retour);
       return *(T*)&L_retour;
    }
    
    int main()
    {
       std::vector<A> L_vectA;
       L_vectA.push_back(A(1,1));
       L_vectA.push_back(A(2,2));
       L_vectA.push_back(A(3,3));
       L_vectA.push_back(A(4,4));
       
       std::vector<B> L_vectB;
    // en rouge ce qui ne compile pas:
       std::for_each(
          L_vectA.begin(),
          L_vectA.end(),
          std::for_each(
                L_vectA.begin(),
                L_vectA.end(),
                boost::bind(
                   &std::vector<B>::push_back,
                   &L_vectB,
                   boost::bind(&Generer<B>,boost::bind(&boost::in_place,_1))
               )
             );
         )
       );
    }
    Si quelque a une piste, je suis preneur.
    Merci.

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    C'est quoi l'erreur ?
    J'imagine que c'est &boost::in_place qui marche pas parce qu'il peut pas savoir quelle surcharge sélectionner.

    La meilleure solution semble de faire une véritable fonction retardée pour in_place.
    http://spirit.sourceforge.net/dl_doc...lazy_functions

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Effectivement, ça n'arrive pas à compiler. En fait, il ne sais pas comment traiter in_place dans bind.
    Je vais regardé avec ton lien.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    J'ai trouvé une solution:
    La fonction générique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    template<class TypedInPlaceFactory>
    typename TypedInPlaceFactory::value_type Generer(TypedInPlaceFactory const& aFactory)
    {
       char L_retour[sizeof(typename TypedInPlaceFactory::value_type)];
       aFactory.apply(L_retour);
       return *(typename TypedInPlaceFactory::value_type*)&L_retour;
    }
    Mes classes tests:
    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
    struct A
    {
       int m_1;
       int m_2;
       A(int P_1=0,int P_2=0):m_1(P_1),m_2(P_2){}
    };
     
    class B
    {
    public:
       B(const A&P_a):m_a(P_a)
       {}
     
       A m_a;
    };
    Le bind de la mort:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    boost::bind(
                &Generer<boost::typed_in_place_factory1<B,A> >,
                boost::bind(static_cast<boost::typed_in_place_factory1<B,A> (*)(A const&)>(&boost::in_place<B,A>),_1)
    L'exemple devient:
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <vector>
    #include <boost/bind.hpp>
    #include <boost/utility/typed_in_place_factory.hpp>
     
    struct A
    {
       int m_1;
       int m_2;
       A(int P_1=0,int P_2=0):m_1(P_1),m_2(P_2){}
    };
     
    class B
    {
    public:
       B(const A&P_a):m_a(P_a)
       {}
     
       A m_a;
    };
     
    template<class TypedInPlaceFactory>
    typename TypedInPlaceFactory::value_type Generer(TypedInPlaceFactory const& aFactory)
    {
       char L_retour[sizeof(typename TypedInPlaceFactory::value_type)];
       aFactory.apply(L_retour);
       return *(typename TypedInPlaceFactory::value_type*)&L_retour;
    }
     
    std::ostream& operator<<(std::ostream& P_flux, const B&P_b)
    {
       return P_flux<<"( "<<P_b.m_a.m_1<<" , "<<P_b.m_a.m_2<<" )\n";
    }
     
    int main()
    {
       std::vector<A> L_vectA;
       L_vectA.push_back(A(1,1));
       L_vectA.push_back(A(2,2));
       L_vectA.push_back(A(3,3));
       L_vectA.push_back(A(4,4));
     
       A a1;
       A a2;
     
       std::vector<B> L_vectB;
       std::for_each(
          L_vectA.begin(),
          L_vectA.end(),
          boost::bind(
             &std::vector<B>::push_back
             ,&L_vectB
             ,boost::bind(
                &Generer<boost::typed_in_place_factory1<B,A> >,
                boost::bind(static_cast<boost::typed_in_place_factory1<B,A> (*)(A const&)>(&boost::in_place<B,A>),_1)
             )
          )
       );
     
       std::copy(
          L_vectB.begin(),
          L_vectB.end(),
          std::ostream_iterator<B>(std::cout)
       );
     
       return std::cin.get();
    }
    1/je suis obligé d'utiliser typed_in_place_factory pour spécifier le type de l'objet.
    2/ Je suis obligé d'instancier explicitement boost::in_place pour avoir une vrai adresse de fonction
    3/ Sous gcc (mais pas sous Visual), je suis obligé de caster explicitement cette instance de boost::in_place.
    Mais ça me plait pas trop, ça me donne l'impression de préciser beaucoup de chose de la cuisine interne de boost::in_place.
    Je vais voir.

  5. #5
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Tu fais du cast de pointeur de fonction pour selectionner la surcharge.
    Il y a beaucoup plus élégant, faire une fonction retardée.

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    loufoque a totalement raison.

    Tu trouveras surement plus de choses avec "lazy function" dans la doc de Boost (Phoenix principalement) pour ce faire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Boost thread avec fonction membre non statique.
    Par Klaim dans le forum Boost
    Réponses: 2
    Dernier message: 11/08/2007, 02h58
  2. [boost] Problème avec boost::function
    Par Bakura dans le forum Boost
    Réponses: 3
    Dernier message: 22/03/2007, 20h08
  3. [BOOST] Problème avec les threads
    Par SOAD08 dans le forum Dev-C++
    Réponses: 7
    Dernier message: 08/10/2006, 10h23
  4. Erreur de compilation de boost::date_time avec mingw
    Par shenron666 dans le forum Code::Blocks
    Réponses: 1
    Dernier message: 26/08/2006, 18h18
  5. boost - Probleme avec compilateur C++ de visual studio 2005
    Par gilles641 dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 24/01/2006, 19h03

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