不能在非 Boost 版本的 Asio 中使用 asio::placeholders::error
Can't use asio::placeholders::error in non-Boost version of Asio
我正在尝试在项目中使用非 Boost 版本的 Asio。我正在写回传给 stream_protocol::acceptor::async_accept
。签名需要 asio::placeholders::error
才能传递,但是当我这样做时,出现以下错误:
error: no member named 'error' in namespace 'asio::placeholders'
根据源代码,我可以看到错误存在,但类型为 undefined
,这对我来说是新的。我错过了什么吗?我应该对库进行某种预处理吗?
简而言之,使用 std::placeholders::_1
而不是 asio::placeholders:error
。
Asio 仅在使用 Boost.Bind 时支持方便的占位符变量。 error
占位符 documentation 表示:
An argument placeholder, for use with boost::bind()
, ...
使用std::bind()
创建处理程序时,需要使用std::bind
的占位符。 async_accept()
operation accepts a handler that meets the AcceptHandler类型要求:
An accept handler must meet the requirements for a handler. A value h
of an accept handler class should work correctly in the expression h(ec)
, where ec
is an lvalue of type const error_code
.
当用 std::bind()
创建一个仿函数作为 AcceptHandler 时,如果希望获得 error_code
参数,那么使用 std::placeholders::_1
:
void handle_accept(const std::error_code&);
acceptor.async_accept(server_socket, std::bind(&handle_accept,
std::placeholders::_1 /* error_code */));
这是一个完整的最小示例 demonstrating,使用 std::bind()
。请注意,coliru 似乎没有可用的 Asio 独立版本,但示例应该足够了:
#include <iostream>
#include <functional>
#include <boost/asio.hpp>
void handle_accept(const boost::system::error_code& error_code)
{
std::cout << "handle_accept: " << error_code.message() << std::endl;
}
void noop() {}
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket server_socket(io_service);
tcp::socket client_socket(io_service);
// Connect client and server sockets.
acceptor.async_accept(server_socket, std::bind(&handle_accept,
std::placeholders::_1 /* error_code */));
client_socket.async_connect(acceptor.local_endpoint(), std::bind(&noop));
io_service.run();
}
输出:
handle_accept: Success
可选地,如果希望更冗长一点,则可以使用命名占位符:
namespace asio_placeholders
{
auto error = std::placeholders::_1;
}
// ...
acceptor.async_accept(server_socket, std::bind(&handle_accept,
asio_placeholders::error));
在源代码中观察到的unspecified
类型仅在生成文档时使用,如code:
所示
#if defined(GENERATING_DOCUMENTATION)
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the error argument of a handler for any of the asynchronous functions.
unspecified error;
// ...
#elseif
我正在尝试在项目中使用非 Boost 版本的 Asio。我正在写回传给 stream_protocol::acceptor::async_accept
。签名需要 asio::placeholders::error
才能传递,但是当我这样做时,出现以下错误:
error: no member named 'error' in namespace 'asio::placeholders'
根据源代码,我可以看到错误存在,但类型为 undefined
,这对我来说是新的。我错过了什么吗?我应该对库进行某种预处理吗?
简而言之,使用 std::placeholders::_1
而不是 asio::placeholders:error
。
Asio 仅在使用 Boost.Bind 时支持方便的占位符变量。 error
占位符 documentation 表示:
An argument placeholder, for use with
boost::bind()
, ...
使用std::bind()
创建处理程序时,需要使用std::bind
的占位符。 async_accept()
operation accepts a handler that meets the AcceptHandler类型要求:
An accept handler must meet the requirements for a handler. A value
h
of an accept handler class should work correctly in the expressionh(ec)
, whereec
is an lvalue of typeconst error_code
.
当用 std::bind()
创建一个仿函数作为 AcceptHandler 时,如果希望获得 error_code
参数,那么使用 std::placeholders::_1
:
void handle_accept(const std::error_code&);
acceptor.async_accept(server_socket, std::bind(&handle_accept,
std::placeholders::_1 /* error_code */));
这是一个完整的最小示例 demonstrating,使用 std::bind()
。请注意,coliru 似乎没有可用的 Asio 独立版本,但示例应该足够了:
#include <iostream>
#include <functional>
#include <boost/asio.hpp>
void handle_accept(const boost::system::error_code& error_code)
{
std::cout << "handle_accept: " << error_code.message() << std::endl;
}
void noop() {}
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket server_socket(io_service);
tcp::socket client_socket(io_service);
// Connect client and server sockets.
acceptor.async_accept(server_socket, std::bind(&handle_accept,
std::placeholders::_1 /* error_code */));
client_socket.async_connect(acceptor.local_endpoint(), std::bind(&noop));
io_service.run();
}
输出:
handle_accept: Success
可选地,如果希望更冗长一点,则可以使用命名占位符:
namespace asio_placeholders
{
auto error = std::placeholders::_1;
}
// ...
acceptor.async_accept(server_socket, std::bind(&handle_accept,
asio_placeholders::error));
在源代码中观察到的unspecified
类型仅在生成文档时使用,如code:
#if defined(GENERATING_DOCUMENTATION)
/// An argument placeholder, for use with boost::bind(), that corresponds to
/// the error argument of a handler for any of the asynchronous functions.
unspecified error;
// ...
#elseif