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.