如何在Boost.Process v2的async_wait中组合as_tuple与use_awaitable?
解决Boost.Process v2 async_wait中asio::as_tuple与asio::use_awaitable的组合问题
在原生Boost.Asio协程中,正确组合asio::as_tuple和asio::use_awaitable适配Boost.Process v2的async_wait操作,需要注意完成适配器的正确嵌套方式,以下是两种可行的写法:
写法1:直接传递asio::as_tuple(asio::use_awaitable)(需Boost.Asio 1.78+)
如果你的Boost版本足够新(Asio 1.78及以上),可以直接将asio::as_tuple包装后的use_awaitable作为完成token传入async_wait:
#include <boost/asio.hpp> #include <boost/process/v2.hpp> #include <coroutine> namespace asio = boost::asio; namespace bpv2 = boost::process::v2; asio::awaitable<void> run_process() { asio::io_context io; bpv2::process proc(io, "/bin/echo", {"hello"}); // 正确写法:直接传递as_tuple包装的use_awaitable auto [ec, exit_code] = co_await proc.async_wait(asio::as_tuple(asio::use_awaitable)); if (!ec) { std::cout << "Process exited with code: " << exit_code << std::endl; } else { std::cerr << "Wait error: " << ec.message() << std::endl; } } int main() { asio::io_context io; asio::co_spawn(io, run_process(), asio::detached); io.run(); return 0; }
写法2:用asio::async_initiate手动适配(兼容旧版本Asio)
如果你的Boost版本较旧,或者直接传递出现编译问题,可以通过asio::async_initiate手动完成适配器的绑定:
#include <boost/asio.hpp> #include <boost/process/v2.hpp> #include <coroutine> namespace asio = boost::asio; namespace bpv2 = boost::process::v2; asio::awaitable<void> run_process() { asio::io_context io; bpv2::process proc(io, "/bin/echo", {"hello"}); // 正确写法:用async_initiate适配as_tuple和use_awaitable auto [ec, exit_code] = co_await asio::async_initiate<asio::use_awaitable_t<>, void(asio::error_code, bpv2::exit_code)>( [&proc](auto&& token) { proc.async_wait(std::forward<decltype(token)>(token)); }, asio::as_tuple(asio::use_awaitable) ); if (!ec) { std::cout << "Process exited with code: " << exit_code << std::endl; } else { std::cerr << "Wait error: " << ec.message() << std::endl; } } int main() { asio::io_context io; asio::co_spawn(io, run_process(), asio::detached); io.run(); return 0; }
为什么你的写法编译失败?
你尝试的两种写法都存在适配逻辑错误:
co_await proc.async_wait(asio::as_tuple(asio::use_awaitable)):部分旧版本Boost.Process v2的async_wait对完成token的类型推导存在限制,无法直接识别asio::as_tuple_t包装的use_awaitable;co_await proc.async_wait(asio::as_tuple)(asio::use_awaitable):asio::as_tuple是一个函数,需要传入完成token后返回适配器,这种写法相当于先调用无参的asio::as_tuple(),再将use_awaitable作为参数传递,完全不符合API的调用逻辑。
内容的提问来源于stack exchange,提问作者Sean Champ
相关产品推荐
相关产品推荐

