C++ 启动一个异步操作并产生结果

C++ 启动一个异步操作并产生结果,c++,boost-asio,c++20,c++-coroutine,C++,Boost Asio,C++20,C++ Coroutine,我目前正在从事一个使用boost asio进行联网的项目。我想实现一个如下所示的函数: template<command T, response R = typename T::response_type> auto send_command(T c) -> boost::asio::awaitable<R> { // ... } // returns the awaitable for the coroutine to suspend return as

我目前正在从事一个使用boost asio进行联网的项目。我想实现一个如下所示的函数:

template<command T, response R = typename T::response_type>
auto send_command(T c) -> boost::asio::awaitable<R> {
    // ...
}
// returns the awaitable for the coroutine to suspend
return asio::async_initiate<CompletionToken, void(void)>(
    [self = shared_from_this()](auto&& handler) {
        self->callback_queue.push(std::forward<decltype(handler)>(handler));
    }
);

// later

auto& resume = callback_queue.front();
resume(); // resume the suspended coroutine
auto callback = std::exchange(callback_queue[command_id], {});
if (result) {
    // resumes the coroutine normally with the result
    callback(boost::system::error_code{}, *result);
} else {
    // Throws exception in the coroutine
    callback(make_error_code(boost::system::errc::operation_canceled), R{});
}
但我不知道当返回值不是空的时候,应该把它放在哪里

auto const command_id = std::int32_t{...};

auto& resume_command = commands_continuations[command_id];
resume_command(response_result); // Send the `co_await` result in parameters??

我只是对如何发送可等待的返回以及如何启动异步操作并产生结果感到困惑。

事实证明,异步操作可以接受许多固定签名

void(void)
是其中之一,但是为了得到结果,我们可以简单地使用
void(T)

回调采用与签名
void(boost::system::error\u code,R)
匹配的仅移动函数的形式。我这样称呼它:

template<command T, response R = typename T::response_type>
auto send_command(T c) -> boost::asio::awaitable<R> {
    // ...
}
// returns the awaitable for the coroutine to suspend
return asio::async_initiate<CompletionToken, void(void)>(
    [self = shared_from_this()](auto&& handler) {
        self->callback_queue.push(std::forward<decltype(handler)>(handler));
    }
);

// later

auto& resume = callback_queue.front();
resume(); // resume the suspended coroutine
auto callback = std::exchange(callback_queue[command_id], {});
if (result) {
    // resumes the coroutine normally with the result
    callback(boost::system::error_code{}, *result);
} else {
    // Throws exception in the coroutine
    callback(make_error_code(boost::system::errc::operation_canceled), R{});
}

关于它的文档中有更多信息

我知道传递给
async_result
的签名决定了您的令牌类型的专门化最终将推断为什么返回类型。我还不熟悉
async\u initiate
——我发现这方面的文档非常薄弱(基本上没有)。因此,我无法将其显示为可供使用,但它可能有助于显示其他类型的完成标记的类似物: