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 :

Problème avec bind


Sujet :

Boost C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    79
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mars 2007
    Messages : 79
    Points : 48
    Points
    48
    Par défaut Problème avec bind
    Bonjour,

    J'ai une classe appelé Countdown qui gère un compte à rebours. Pour cela, j'utilise boost::asio::deadline_timer en asynchrone.
    J'aimerai passer en paramètre de mon constructeur la fonction a déclencher lorsque le compte à rebours a expiré et démarrer le compte à rebours par une fonction start.

    Mon problème est que je n'arrive pas à déclencher la fonction passée en paramètre.

    Voici le code:

    Countdown.hpp
    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
    #ifndef COUNTDOWN_HPP_
    #define COUNTDOWN_HPP_
     
    #include <boost/bind.hpp>
    #include <boost/asio.hpp>
    #include <boost/function.hpp>
     
    class Countdown
    {
    private:
    	bool m_actived;
    	bool m_suspended;
    	boost::asio::deadline_timer m_runTimer;
    	boost::function<void(const boost::system::error_code& error)> m_handler;
     
    public:
    	Countdown(boost::asio::io_service& ioService,boost::function<void(const boost::system::error_code& error)> handler);
    	~Countdown();
    	void start();
    	void suspend();
    	void stop();
    	void setValue(short value);
    };
     
     
    #endif /* COUNTDOWN_HPP_ */
    Countdown.cpp
    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
    #include "Countdown.hpp"
     
    Countdown::Countdown(boost::asio::io_service& ioService,boost::function<void(const boost::system::error_code& error)> handler)
    : m_actived(true),m_suspended(false),m_runTimer(ioService),m_handler(handler)
    {
    	m_runTimer.expires_from_now(boost::posix_time::seconds(1));
    }
     
    Countdown::~Countdown()
    {
    	m_actived = false;
    	m_runTimer.cancel();
    }
     
    void Countdown::start()
    {
    	m_actived = true;
    	m_runTimer.async_wait(m_handler);
    }
     
    void Countdown::suspend()
    {
    	if(m_suspended)
    	{
     
    	}
    	else
    	{
     
    	}
    }
     
    void Countdown::stop()
    {
    	m_actived = false;
    	m_runTimer.cancel();
    }
     
    void Countdown::setValue(short value)
    {
    	m_runTimer.expires_from_now(boost::posix_time::seconds(value));
    }
    main.cpp
    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
    #include <iostream>
    #include <windows.h>
     
    #include "Countdown.hpp"
     
    void expireHandler(const boost::system::error_code& error)
    {
    	std::cout << "end of the countdown" << std::endl;
    }
     
    int main() {
    	boost::asio::io_service ioService;
    	boost::system::error_code error;
    	Countdown countdown(ioService,
    			boost::bind(
    					&expireHandler,
    					error
    	));
    	countdown.setValue(5);
    	std::cout << "Start of the countdown" << std::endl;
    	countdown.start();
    	Sleep(10000);
    	std::cout << "end of the program" << std::endl;
    	return 0;
    }
    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Start of the countdown
    end of the program

  2. #2
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Le truc bizarre que je vois c'est dans ton bind tu passes directement une copie locale de error, or c'est pas comme ça que tu dois faire.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Countdown countdown(ioService,
    			boost::bind(
    					&expireHandler,
    					boost::asio::placeholders::error
    	));
    D'un autre côté, ça m'étonne que tu n'as pas d'erreur de compilation vu que après ton bind, ton expireHandler devrait devenir une fonction sans argument. Vu que avec ton bind tu dis : "le premier paramètre de expireHandler sera toujours une copie locale de boost::system::error_code".

    Mais en fait tu n'es même pas obligé d'utilisé un bind, passer simplement ta fonction en paramètre devrait suffire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Countdown countdown(ioService, &expireHandler);

  3. #3
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Le bind est faux il faire Countdown countdown(ioService, boost::bind(&expireHandler, _1));

    Une petite exemple pour bien comprendre. Ce code :
    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
    #include <iostream>
    #include <boost/bind.hpp>
     
    void foo(int i)
    {
       std::cout << i << std::endl;
    }
     
    int main() 
    {
       auto b1 = boost::bind(&foo, 4);
       b1(5); // 5 ne va pas être utilisé, le premier argument est déjà bindé
       b1(6); // 6 ne va pas être utilisé, le premier argument est déjà bindé
       b1();
     
       auto b2 = boost::bind(&foo, _1); // _1 est un placeholder
       b2(5);
       b2(6);
       //b2(); // ne compile pas, il faut un argument
    }
    affiche
    Mais comme l'a dit trademark ici on peut faire encore plus simple car vu que ton constructeur prend une std::function il n'y a même pas besoin de faire un bind, tu peux simplement passer l'adresse de la fonction.

Discussions similaires

  1. Problème avec binding image wpf c#
    Par cocobelle89 dans le forum C#
    Réponses: 2
    Dernier message: 23/04/2013, 11h44
  2. Problème avec bind
    Par Pwato dans le forum Boost
    Réponses: 3
    Dernier message: 22/10/2012, 18h19
  3. Problème avec bind
    Par _mumu_ dans le forum Administration système
    Réponses: 5
    Dernier message: 03/09/2009, 12h43
  4. Problème avec Bind
    Par Nouss dans le forum Debian
    Réponses: 13
    Dernier message: 09/07/2008, 11h05
  5. Probléme avec Bind
    Par rach20032 dans le forum Réseau
    Réponses: 2
    Dernier message: 06/07/2007, 11h36

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