這篇Demo將敘兩點。
1.調用bind,並搭配占位符placeholders::error將函數或成員函數適配為asio要求的handler。使用steady_timer,結合轉換后的handler,實現回調函數的調用。
2.通過lambda表達式將函數或成員函數轉換成符合asio要求的handler。使用steady_timer,結合轉換后的handler,實現回調函數的調用。
#pragma once #define BOOST_ASIO_DISABLE_STD_CHRONO #include <boost/asio.hpp> #include <boost/chrono.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/function.hpp> #include <boost/bind.hpp> using namespace boost::asio; class timer_with_func { typedef timer_with_func this_type; //定義自身別名,方便使用 private: int m_icount = 0; //計數器成員變量 int m_icount_max = 0; //計數器上限 boost::function<void()> m_f; //function對象,持有無參無返回的可調用物 steady_timer m_t; //asio定時器對象 public: template<typename F> //模板類型,可以接收任意可調用物 timer_with_func(io_service& io, int x, F func) : m_icount_max(x), //初始化計數器 m_f(func), //初始化回調函數 m_t(io) //啟動計時器 { m_t.expires_from_now(boost::chrono::milliseconds(2000)); init(); //異步等待計時器,注冊回調函數 } //bind表達式法:使用bind搭配占位符placeholders::error將函數或成員函數適配為asio要求的handler //private: // void init() // { // m_t.async_wait(bind( //使用bind綁定成員函數 // &this_type::handler, this, //傳遞this指針 // boost::asio::placeholders::error)); //使用error站位符傳遞錯誤碼 // } // // void handler(const boost::system::error_code&) // { // if (m_icount++ >= m_icount_max) //如果計數器到達上限則退出 // { // return; // } // // m_f(); //調用function對象 // // m_t.expires_from_now(boost::chrono::milliseconds(2000)); //設置定時器的終止時間為2s之后 // // m_t.async_wait(bind( //再次啟動定時器,異步等待 // &this_type::handler, this, // boost::asio::placeholders::error)); // } //lambda表達式法: private: typedef void(handler_type)(const boost::system::error_code&); //定義handler類型,一定要這樣做 boost::function<handler_type> m_handler = //lambda的handler [&](const boost::system::error_code&) //捕獲引用,包括this { if (m_icount++ >= m_icount_max) { return; } m_f(); m_t.expires_from_now(boost::chrono::milliseconds(2000)); //設置定時器終止時間 m_t.async_wait(m_handler); //再次異步等待 }; void init() { m_t.async_wait(m_handler); //異步等待,注冊回調函數 } }; //timer_with_func定義結束
調用文件
#include <iostream> #define BOOST_ASIO_DISABLE_STD_CHRONO #include <boost/asio.hpp> #include <boost/chrono.hpp> #include <boost/system/error_code.hpp> #include <boost/asio/steady_timer.hpp> #include "time_with_func.h" using namespace boost::asio; int main() { io_service io; //steady_timer t1(io); //t1.expires_from_now(boost::chrono::milliseconds(5000)); //std::cout << t1.expires_at() << std::endl; //std::cout << t1.expires_from_now() << std::endl; ////t1.wait(); //t1.async_wait( // [](const boost::system::error_code& ec) { // std::cout << "hello asio." << std::endl; //}); timer_with_func t1(io, 5, [] {std::cout << "hello timer1." << std::endl; }); //啟動第一個定時器 timer_with_func t2(io, 5, [] {std::cout << "hello timer2." << std::endl; }); //啟動第二個定時器 io.run(); //io_service等待異步調用結束 std::cout << "Hello World!\n"; getchar(); }
問題:
定時器對象一旦創建,就會開始計時。如上,在對定時器進行初始化是分兩步進行,io_service在成員列表里就賦給了定時器,而在構造函數內,還給定時器賦了一個終止時間。這樣定時器是在哪一步開始計時?