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 :

smart_ptr, range et bind


Sujet :

Boost C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut smart_ptr, range et bind
    Bonjour à tous, j'ai un problème avec l'utilisation des smart pointer, des ranges de boost et de bind:
    Soit le code suivant qui a pour but d'afficher les éléments d'une collection (de pointeurs de A) pour lesquels une fonction membre renvoie vrai:
    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
    struct A
    {
    	bool ok() const { return true; }
    };
     
    #include <vector>
    #include <boost/shared_ptr.hpp>
    #include <boost/lambda/bind.hpp>
    #include <boost/lambda/lambda.hpp>
    #include <boost/range/adaptor/filtered.hpp>
    #include <boost/foreach.hpp>
     
    #define foreach BOOST_FOREACH
     
    int main()
    {
    	using namespace boost;
    	using namespace boost::lambda;
    	using namespace boost::adaptors;
     
    	//on définit un type pointeur sur A
    	typedef A* PtrA; //(1)
     
    	//une collection de pointeurs de A
    	std::vector<PtrA> listA;
     
    	//on affiche uniquement les A pour lesquel ok est vrai
    	foreach(PtrA& a, listA | filtered(bind(&A::ok, _1))) //(2)
    		std::cout << "ok" << std::endl;
    }
    Ce code compile parfaitement mais si maintenant je remplace la ligne (1) par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef shared_ptr<A> PtrA;
    , le compilateur me sort:
    error C2665: 'boost::lambda::function_adaptor<Func>::apply'*: aucune des 2 surcharges n'a pu convertir tous les types d'arguments
    Par contre si je remplace la ligne (2) par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach(PtrA& a, listA | filtered(bind(&A::ok, bind(&PtrA::get, _1))))
    le code compile.
    Je pensais que les smart pointer s'utilisaient comme des pointeurs, je ne comprend pas pourquoi je doit repasser par le pointeur "brut" (en appelant PtrA::get) pour pouvoir utiliser la fonction membre ok de A?

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    J'ajoute quelques précisions: le compilateur est visual 2008, j'ai également à disposition visual 2010 express edition et si j'utilise les éléments de la nouvelle norme, ça compile! :
    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
     
    #include <vector>
    #include <memory>  //pour std::shared_ptr
    #include <functional>  //pour std::bind
    #include <boost/range/adaptor/filtered.hpp>
    #include <boost/foreach.hpp>
     
    #define foreach BOOST_FOREACH
     
    int main()
    {
    	using namespace boost::adaptors;
     
    	//on définit un type pointeur sur A
    	typedef std::shared_ptr<A> PtrA;
     
    	//une collection de pointeurs de A
    	std::vector<PtrA> listA;
     
    	//on affiche uniquement les A pour lesquel ok est vrai
    	foreach(PtrA& a, listA | filtered(std::bind(&A::ok, std::placeholders::_1)))
    		std::cout << "ok" << std::endl;
    }
    Je ne comprend toujours pas pourquoi cela ne fonctionne pas avec les versions de boost (version 1.46). D'autant plus que je ne pourrais pas utiliser la version 2010 de visual

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Bon désolé d'avoir ouvert une discussion pour rien! J'ai fini par trouver: il ne faut pas utiliser le bind de boost/lambda mais directement celui de boost/bind. Dites moi si je dois supprimer la discussion. Dans tout les cas, voici le code fonctionnel:
    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
    struct A
    {
    	bool ok() const { return true; }
    };
     
    #include <vector>
    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/range/adaptor/filtered.hpp>
    #include <boost/foreach.hpp>
     
    #define foreach BOOST_FOREACH
     
    int main()
    {
    	using namespace boost;
    	using namespace boost::adaptors;
     
    	//on définit un type pointeur sur A
    	typedef shared_ptr<A> PtrA;
     
    	//une collection de pointeurs de A
    	std::vector<PtrA> listA;
     
    	//on affiche uniquement les A pour lesquel ok est vrai
    	foreach(PtrA& a, listA | filtered(bind(&A::ok, _1)))
    		std::cout << "ok" << std::endl;
    }

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

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