在 boost::deadline_timer 上创建包装器,无法将参数传递给处理程序函数
Creating wrapper over boost::deadline_timer, not able to pass parameter to handler function
我正在尝试创建一个简单的 BoostTimer
class,它包含 deadline_timer
的基本功能,例如 async_wait
和 cancel
,这样我的程序只调用 startTimer
和 killTimer
,我写了下面的代码
boosttimer.h
#ifndef __BOOST_TIMER__
#define __BOOST_TIMER__
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/chrono.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/function.hpp>
class BoostTimer{
public:
typedef boost::asio::deadline_timer deadline_timer;
typedef deadline_timer::duration_type duration;
typedef boost::function<void (boost::system::error_code, BoostTimer&)> handler_function;
BoostTimer(boost::asio::io_service& io_service, duration interval, handler_function handler);
~BoostTimer();
void startTimer();
void killTimer();
private:
deadline_timer _timer;
boost::asio::io_service& _ioService;
duration _interval;
handler_function _handler;
};
#endif
boosttimer.cpp
#include "boosttimer.h"
BoostTimer::BoostTimer(boost::asio::io_service& io_service, duration interval, handler_function handler) :
_timer(io_service),
_ioService(io_service),
_interval(interval),
_handler(handler)
{
}
BoostTimer::~BoostTimer()
{
}
void BoostTimer::startTimer()
{
_timer.expires_from_now(_interval);
_timer.async_wait(boost::bind(_handler, boost::asio::placeholders::error, boost::ref(*this))); //trying to pass placeholder argument but somehow it doesn't work
}
void BoostTimer::killTimer()
{
_timer.cancel();
}
timertest.cpp
#include <iostream>
#include <boost/asio.hpp>
#include "boosttimer.h"
//void timer_handler(const boost::system::error_code& /*e*/) // not able to take parameters
void timer_handler() //it runs fine without parameters
{
std::cout<<"timer function has been called" << std::endl;
}
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(5), boost::bind(&timer_handler));
timer.startTimer();
io_service.run();
return 0;
}
我的问题是如何将参数从 BoostTimer
class 的 startTimer
函数传递到我的处理程序函数?我试过了,但我遗漏了一些东西。
如果您只想传递调用者的参数:
void timer_handler(std::string const& arg1, int arg2)
{
std::cout<<"timer function has been called with arg1='" << arg1 <<"', arg2=" << arg2 << std::endl;
}
int main()
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(5), boost::bind(&timer_handler, "This is arg1", 42));
timer.startTimer();
io_service.run();
return 0;
}
看到了Live On Coliru,输出:
timer function has been called with arg1='This is arg1', arg2=42
同时传递 ec
和 *this
:
CAVEAT I think this seriously breaks any encapsulation and makes the whole class basically redundant. Consider not calling the completion handler in case of cancellation e.g. Also, let the caller bind the objects instances it requires (it's weird for the user-defined handler to require a reference to BoostTimer
- that's tight coupling in the wrong direction)
void timer_handler(boost::system::error_code ec, BoostTimer& instance, std::string const& arg1, int arg2) //it runs fine without parameters
{
std::cout<<"timer function has been called with arg1='" << arg1 <<"', arg2=" << arg2 << " (" << ec.message() << ")\n";
}
int main()
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(1), boost::bind(&timer_handler, _1, _2, "This is arg1", 42));
timer.startTimer();
io_service.run();
return 0;
}
也看到了Live On Coliru,输出:
timer function has been called with arg1='This is arg1', arg2=42 (Success)
我正在尝试创建一个简单的 BoostTimer
class,它包含 deadline_timer
的基本功能,例如 async_wait
和 cancel
,这样我的程序只调用 startTimer
和 killTimer
,我写了下面的代码
boosttimer.h
#ifndef __BOOST_TIMER__
#define __BOOST_TIMER__
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/chrono.hpp>
#include <boost/chrono/duration.hpp>
#include <boost/function.hpp>
class BoostTimer{
public:
typedef boost::asio::deadline_timer deadline_timer;
typedef deadline_timer::duration_type duration;
typedef boost::function<void (boost::system::error_code, BoostTimer&)> handler_function;
BoostTimer(boost::asio::io_service& io_service, duration interval, handler_function handler);
~BoostTimer();
void startTimer();
void killTimer();
private:
deadline_timer _timer;
boost::asio::io_service& _ioService;
duration _interval;
handler_function _handler;
};
#endif
boosttimer.cpp
#include "boosttimer.h"
BoostTimer::BoostTimer(boost::asio::io_service& io_service, duration interval, handler_function handler) :
_timer(io_service),
_ioService(io_service),
_interval(interval),
_handler(handler)
{
}
BoostTimer::~BoostTimer()
{
}
void BoostTimer::startTimer()
{
_timer.expires_from_now(_interval);
_timer.async_wait(boost::bind(_handler, boost::asio::placeholders::error, boost::ref(*this))); //trying to pass placeholder argument but somehow it doesn't work
}
void BoostTimer::killTimer()
{
_timer.cancel();
}
timertest.cpp
#include <iostream>
#include <boost/asio.hpp>
#include "boosttimer.h"
//void timer_handler(const boost::system::error_code& /*e*/) // not able to take parameters
void timer_handler() //it runs fine without parameters
{
std::cout<<"timer function has been called" << std::endl;
}
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(5), boost::bind(&timer_handler));
timer.startTimer();
io_service.run();
return 0;
}
我的问题是如何将参数从 BoostTimer
class 的 startTimer
函数传递到我的处理程序函数?我试过了,但我遗漏了一些东西。
如果您只想传递调用者的参数:
void timer_handler(std::string const& arg1, int arg2)
{
std::cout<<"timer function has been called with arg1='" << arg1 <<"', arg2=" << arg2 << std::endl;
}
int main()
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(5), boost::bind(&timer_handler, "This is arg1", 42));
timer.startTimer();
io_service.run();
return 0;
}
看到了Live On Coliru,输出:
timer function has been called with arg1='This is arg1', arg2=42
同时传递 ec
和 *this
:
CAVEAT I think this seriously breaks any encapsulation and makes the whole class basically redundant. Consider not calling the completion handler in case of cancellation e.g. Also, let the caller bind the objects instances it requires (it's weird for the user-defined handler to require a reference to
BoostTimer
- that's tight coupling in the wrong direction)
void timer_handler(boost::system::error_code ec, BoostTimer& instance, std::string const& arg1, int arg2) //it runs fine without parameters
{
std::cout<<"timer function has been called with arg1='" << arg1 <<"', arg2=" << arg2 << " (" << ec.message() << ")\n";
}
int main()
{
boost::asio::io_service io_service;
BoostTimer timer(io_service,boost::posix_time::seconds(1), boost::bind(&timer_handler, _1, _2, "This is arg1", 42));
timer.startTimer();
io_service.run();
return 0;
}
也看到了Live On Coliru,输出:
timer function has been called with arg1='This is arg1', arg2=42 (Success)