创建一个可用于启动基于协程的复合异步操作的初始化函数对象。
template< typename... Signatures, typename Implementation, typename... IoObjectsOrExecutors> auto co_composed( Implementation && implementation, IoObjectsOrExecutors &&... io_objects_or_executors);
co_composed 工具通过自动适配协程以使其成为可与 async_initiate
一起使用的初始化函数对象,从而简化了复合异步操作的实现。在等待异步操作时,协程会自动使用符合要求的中间完成处理程序。
一个函数对象,其中包含基于协程的复合异步操作的实现。函数对象的第一个参数代表操作的状态,可用于测试取消。其余参数是在完成令牌之后传递给 async_initiate
的参数。
零个或多个 I/O 对象或 I/O 执行器,在操作未完成期间必须维护其上的挂起工作。
默认情况下,对于使用 co_composed 的复合操作,会启用终端按操作取消。要禁用复合操作的取消,或更改其支持的取消类型,请调用状态的 reset_cancellation_state
函数。
以下示例说明了手动错误处理和显式取消检查。完成处理程序通过对状态的 complete
函数进行 co_yield
来调用,该函数永远不会返回。
template <typename CompletionToken> auto async_echo(tcp::socket& socket, CompletionToken&& token) { return boost::asio::async_initiate< CompletionToken, void(boost::system::error_code)>( boost::asio::co_composed( [](auto state, tcp::socket& socket) -> void { state.reset_cancellation_state( boost::asio::enable_terminal_cancellation()); while (!state.cancelled()) { char data[1024]; auto [e1, n1] = co_await socket.async_read_some( boost::asio::buffer(data)); if (e1) co_yield state.complete(e1); if (!!state.cancelled()) co_yield state.complete( make_error_code(boost::asio::error::operation_aborted)); auto [e2, n2] = co_await boost::asio::async_write(socket, boost::asio::buffer(data, n1)); if (e2) co_yield state.complete(e2); } }, socket), token, std::ref(socket)); }
下一个示例展示了基于异常的错误处理和隐式取消检查。通过从协程返回后,使用 co_return
调用完成处理程序。有效的 co_return
值使用传递给 co_composed
函数的完成签名进行指定。
template <typename CompletionToken> auto async_echo(tcp::socket& socket, CompletionToken&& token) { return boost::asio::async_initiate< CompletionToken, void(boost::system::error_code)>( boost::asio::co_composed< void(boost::system::error_code)>( [](auto state, tcp::socket& socket) -> void { try { state.throw_if_cancelled(true); state.reset_cancellation_state( boost::asio::enable_terminal_cancellation()); for (;;) { char data[1024]; std::size_t n = co_await socket.async_read_some( boost::asio::buffer(data)); co_await boost::asio::async_write(socket, boost::asio::buffer(data, n)); } } catch (const boost::system::system_error& e) { co_return {e.code()}; } }, socket), token, std::ref(socket)); }
Header: boost/asio/co_composed.hpp
便捷头文件: boost/asio.hpp