c++ - Binding boost::asio::steady_timer::async_wait -


i want turn call:

timer.async_wait(handler); 

into call:

func(handler); 

so tried using std::bind:

#include <functional>  #include <boost/asio.hpp> #include <boost/asio/steady_timer.hpp> #include <boost/system/error_code.hpp>  using std::bind; using std::function;  using boost::asio::io_service; using boost::asio::steady_timer; using boost::system::error_code;  int main(int, char**) {   using namespace std::placeholders;    io_service io_s;   steady_timer timer (io_s);    // error                                                                                                                                                                                                                                       function<void(function<void(const error_code&)>)> bound =     bind(&steady_timer::async_wait, timer, _1);    return 0; } 

but wont compile! when compiled this:

g++-4.9 -std=c++11 -wall -i/usr/local/include -l/usr/local/lib -lboost_system -o bin main.cpp 

the error message this:

main.cpp:22:46: error: no matching function call 'bind(<unresolved overloaded function type>, boost::asio::steady_timer&, const std::_placeholder<1>&)'  bind(&steady_timer::async_wait, timer, _1); 

i've tried various things (like casting, template arguments, function objects) can't compile.

i'm using boost asio 1.58 , the documentation says following:

template<     typename waithandler> void-or-deduced async_wait(     waithandler handler); 

and here can see waithandler is. don't understand void-or-deduced mean i'm thinking might what's giving me tough time? i've stared @ problem long think i've gotten tunnel vision.

how use std::bind in case?

the type of object returned initiating function (async_*) dependent on handler type provided initiating function. documentation indicates variant void-or-deduced type.

trying use function , bind here have multiple problems:

  • the function signature timer.async_wait() cannot resolved without first specifying exact handler type provided return-type can deduced
  • changing handler type std::function<...> can have unintended consequences, default asio_handler_* hooks invoked rather custom hooks. see this answer more details handler hooks.

instead, consider using custom functor accomplish binding, while allowing handler types passed through asio:

/// @brief custom functor used initiate async_wait operations. template <typename timer> class async_wait_functor { public:   async_wait_functor(timer& timer): timer_(timer) {}    template <typename waithandler>   auto operator()(waithandler handler)   {     return timer_.async_wait(handler);   }  private:   timer& timer_; };  /// @brief auxiliary factory function binding timer. template <typename timer> async_wait_functor<timer> bind_async_wait(timer& timer) {   return async_wait_functor<timer>(timer); }  ...  auto func = bind_async_wait(timer); func(handler); 

here complete example demonstrating using custom functor:

#include <iostream> #include <functional>     #include <boost/asio.hpp> #include <boost/asio/steady_timer.hpp>  /// @brief custom functor used initiate async_wait operations. template <typename timer> class async_wait_functor { public:   async_wait_functor(timer& timer): timer_(timer) {}    template <typename waithandler>   auto operator()(waithandler handler)   {     return timer_.async_wait(handler);   }  private:   timer& timer_; };  /// @brief auxiliary factory function binding timer. template <typename timer> async_wait_functor<timer> bind_async_wait(timer& timer) {   return async_wait_functor<timer>(timer); }  int main() {   boost::asio::io_service io_service;   boost::asio::steady_timer timer(io_service);   auto handler = [](const boost::system::error_code&) {     std::cout << "in handler" << std::endl;   };    auto func = bind_async_wait(timer);   func(handler);    timer.cancel();   io_service.run(); } 

when ran, outputs:

in handler 

the documentation details how return type determined:

by default, initiating functions return void. case when handler function pointer, c++11 lambda, or function object produced boost::bind or std::bind.

for other types, return type may customised via [...] specialisation of async_result template, used both determine return type , extract return value handler.

for example, boost.asio specializes boost::asio::async_result boost::asio::use_future. when boost::asio::use_future provided handler iniating function, return type std::future.


Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -