简体   繁体   中英

boost::bind arguments of static function

I try to bind boost::asio arguments. Function to bind is static member of structure:

template <typename T>
struct bind_struct{

   typedef boost::system::error_code                         error_code;
   typedef boost::asio::ip::tcp::acceptor                    tcp_acceptor_type;
   typedef std::shared_ptr<boost::asio::ip::tcp::socket>     socket_type;


   static void tcp_on_async_accept(error_code& er,
                                  tcp_acceptor_type* acc,
                                  socket_type socket){
       std::cout << "ok" << std::endl;
   }
   static void good_function(int m){
       std::cout << m << std::endl;
   }


};

Bind operation:

  /*Error*/
  bind_struct<void>::socket_type sock;
  bind_struct<void>::tcp_acceptor_type* acc;
  auto fn = boost::bind(bind_struct<void>::tcp_on_async_accept,
                                                boost::asio::placeholders::error,
                                                acc, sock);
  fn();


  /*Ok*/
  auto fn1 = boost::bind(bind_struct<void>::good_function,_1);
  fn1(10);

What is a problem here? Errors.

fn() fails because the functor expects the first argument passed to it to be able to bind to boost::system::error_code& .

The Boost.Asio documentation for boost::asio::placeholders::error states:

An argument placeholder, for use with boost::bind() , that corresponds to the error argument of a handler for any of the asynchronous functions.

Hence, when the function:

void bind_struct::tcp_on_async_accept(
    boost::system::error_code&,
    boost::asio::ip::tcp::acceptor*,
    std::shared_ptr<boost::asio::ip::tcp::socket>)

is bound with:

boost::asio::ip::tcp::acceptor* acceptor;
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
auto fn = boost::bind(
    bind_struct<void>::tcp_on_async_accept,
    boost::asio::placeholders::error, // _1
    acceptor, socket);

The resulting functor fn can only be invoked when the first argument passed to its invocation can bind to boost::system::error_code& . Thus, the following will fail:

fn();

where as the following will work:

boost::system::error_code error;
fn(error);

Consider reading this blog for a great illustrated example of bind() .


If bind_struct::tcp_on_async_accept() is going to be used as the handler to an async_accept() operation, then consider changing the first parameter type to accept error_code by value or by const reference. The Asynchronous Operations type requirements specifies that the first parameter for handlers is an lvalue of type boost::system::error_code , and the AcceptHandler documentation states if h is a handler and ec is a const error_code , then the expression h(ec) must be valid. As a const error_code cannot be bound to boost::system::error_code& , bind_struct::tcp_on_async_accept() fails to meet the AcceptHandler type requirement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM