You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改boost::asio co_spawn协程返回类型后编译报错,求解决

问题分析与解决

原可运行代码

bool FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  // use a coroutine to accept the connection and receive the file.
  bool result = false;

  asio::co_spawn(m_ioContext,
     [&result, &filePath, _numBytes, this]() mutable
      -> asio::awaitable<void> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            result = ReceiveFile(maybeSock.value(), filePath, _numBytes);
        }
    }, asio::detached);

  m_ioContext.restart();
  m_ioContext.run();

  return result;
}

修改后报错的代码

bool FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  // use a coroutine to accept the connection and receive the file.
  bool result = co_await asio::co_spawn(m_ioContext,
     [&filePath, _numBytes, this]() mutable
      -> asio::awaitable<bool> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            co_return ReceiveFile(maybeSock.value(), filePath, _numBytes);
        }
        co_return false;
    }, asio::detached);

  m_ioContext.restart();
  m_ioContext.run();

  return result;
} 

编译错误信息

Visual Studio 2022(CL版本19.37.32824)

FileTransferBehaviour.cpp(101,42): error C2228: left of '.await_ready' must have 
class/struct/union [MyProject,vcxproj]
FileTransferBehaviour.cpp(101,17): error C2440: 'initializing': cannot convert from 
'void' to 'bool' [MyProject.vcxproj]

GCC 11.4.0

FileTransferBehaviour.cpp:101:19: error: unable to find the promise type for this coroutine
  101 |     bool result = co_await asio::co_spawn(m_ioContext,

问题根源

  1. asio::co_spawn搭配asio::detached返回void,无法被co_await
    当co_spawn使用asio::detached作为完成令牌时,它的返回值是void,而co_await要求操作数必须是可等待对象(awaitable),void不满足这个要求,这直接导致了编译错误。

  2. 外层普通函数不能使用co_await
    C++标准规定:任何包含co_await、co_return或co_yield的函数必须是协程,即返回类型必须是符合协程要求的类型(比如asio::awaitable<T>)。而你的ConnectAndTransferFile返回的是bool,属于普通函数,不能直接使用co_await。

正确修改方案

方案1:将外层函数改为协程(推荐,符合Asio协程设计)

把ConnectAndTransferFile改成返回asio::awaitable<bool>,同时用asio::use_awaitable作为co_spawn的完成令牌,这样co_spawn会返回一个可被co_await的awaitable对象:

asio::awaitable<bool> FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  auto result = co_await asio::co_spawn(m_ioContext,
     [filePath = _filePath, _numBytes, this]() mutable
      -> asio::awaitable<bool> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            co_return ReceiveFile(maybeSock.value(), filePath, _numBytes);
        }
        co_return false;
    }, asio::use_awaitable);

  co_return result;
}

注意:此时调用这个函数的地方也需要是协程,或者用asio::sync_wait来同步获取结果。

方案2:保持外层为普通函数,用asio::sync_wait同步获取协程结果

如果你需要保持ConnectAndTransferFile是普通函数(返回bool),可以用asio::sync_wait来等待协程完成并获取结果,不需要手动调用io_context::run():

bool FileTransferBehaviour::ConnectAndTransferFile(const std::string& _sender,
                                               const std::string& _filePath,
                                               size_t _numBytes)
{
  auto coroutine = [filePath = _filePath, _numBytes, this]() mutable
      -> asio::awaitable<bool> {
        auto maybeSock = co_await CoAwaitClientConnection();
        if (maybeSock.has_value()) {
            co_return ReceiveFile(maybeSock.value(), filePath, _numBytes);
        }
        co_return false;
    };

  return asio::sync_wait(asio::co_spawn(m_ioContext, std::move(coroutine), asio::use_awaitable));
}

这个方案中,asio::sync_wait会自动运行io_context直到协程完成,不需要手动调用restart()和run()。

内容的提问来源于stack exchange,提问作者mark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 22:50:54