chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.85k stars 1.2k forks source link

no type named ‘completion_handler_type’ in ‘class boost::asio::async_result’ #1255

Closed liuaifu closed 1 year ago

liuaifu commented 1 year ago

I am trying to write a stackful coroutine that can be called using boost::spawn. The coroutine starts a thread internally, waits for the thread to finish, and obtains an integer value generated by the thread as the return value of the coroutine. However, I encountered an error. Can any experts please help me take a look? My environment is: VS2022 17.5.1 toolset v143 + Windows 11 + Boost1.81.

#include <iostream>
#include <boost/asio/spawn.hpp>
#include <boost/asio.hpp>
#include <boost/thread/future.hpp>

template<typename CompletionToken>
BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void(boost::system::error_code, int))
async_do_something(BOOST_ASIO_MOVE_ARG(CompletionToken) token)
{
    boost::asio::async_completion<CompletionToken, void(boost::system::error_code, int)> completion(token);

    boost::async(boost::launch::async, [handler = completion.completion_handler]() mutable
    {
        boost::system::error_code ec;
        int result = 0;
        std::this_thread::sleep_for(std::chrono::seconds(5));
        result = 100;

        auto executor = boost::asio::get_associated_executor(handler);
        boost::asio::dispatch(executor, [ec, handler, result]() mutable
        {
            handler(ec, result);
        });
    });

    return completion.result.get();
}

void MyCoroutine(boost::asio::yield_context yield) {
    std::cout << "enter MyCoroutine" << std::endl;
    boost::system::error_code ec;
    int n = async_do_something(yield[ec]);
    if (ec)
        std::cerr << ec.message() << std::endl;
    else
        std::cout << n << std::endl;
    std::cout << "leave MyCoroutine" << std::endl;
}

int main()
{
    boost::asio::io_context ioc;
    boost::asio::spawn(ioc, MyCoroutine);
    ioc.run();
}

严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C2039 "completion_handler_type": 不是 "boost::asio::async_result<boost::asio::basic_yield_context,void (boost::system::error_code,int)>" 的成员 TestAsync D:\library\boost_1_81_0\boost\asio\async_result.hpp 650 错误 C3646 “completion_handler_type”: 未知重写说明符 TestAsync D:\library\boost_1_81_0\boost\asio\async_result.hpp 651 错误 C4430 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int TestAsync D:\library\boost_1_81_0\boost\asio\async_result.hpp 651 错误 C2064 项不会计算为接受 2 个参数的函数 TestAsync C:\Users\laf163\Desktop\TestAsync\TestAsync\TestAsync.cpp 23
错误 C2039 "get": 不是 "boost::asio::async_result<boost::asio::basic_yield_context,void (boost::system::error_code,int)>" 的成员 TestAsync C:\Users\laf163\Desktop\TestAsync\TestAsync\TestAsync.cpp 27


2023/3/11 Ubuntu22.04 gcc9.3.0

$ g++ -c -I../boost_1_81_0 main.cpp In file included from ../boost_1_81_0/boost/asio/detail/handler_type_requirements.hpp:53, from ../boost_1_81_0/boost/asio/impl/execution_context.hpp:18, from ../boost_1_81_0/boost/asio/execution_context.hpp:409, from ../boost_1_81_0/boost/asio/any_io_executor.hpp:23, from ../boost_1_81_0/boost/asio/spawn.hpp:19, from main.cpp:5: ../boost_1_81_0/boost/asio/async_result.hpp: In instantiation of ‘struct boost::asio::async_completion<boost::asio::basic_yield_context, void(boost::system::error_code, int)>’: main.cpp:14:87: required from ‘typename boost::asio::async_result<typename std::decay<_Tp>::type, void(boost::system::error_code, int)>::return_type async_do_something(CompletionToken&&) [with CompletionToken = boost::asio::basic_yield_context; typename boost::asio::async_result<typename std::decay<_Tp>::type, void(boost::system::error_code, int)>::return_type = int]’ main.cpp:38:38: required from here ../boost_1_81_0/boost/asio/async_result.hpp:651:9: error: no type named ‘completion_handler_type’ in ‘class boost::asio::async_result<boost::asio::basic_yield_context, void(boost::system::error_code, int)>’ 651 | completion_handler_type; | ^~~~~~~ ../boost_1_81_0/boost/asio/async_result.hpp:684:62: error: no type named ‘completion_handler_type’ in ‘class boost::asio::async_result<boost::asio::basic_yield_context, void(boost::system::error_code, int)> ’ 684 | completion_handler_type&, completion_handler_type>::type completion_handler; | ^~~~~~ main.cpp: In instantiation of ‘typename boost::asio::async_result<typename std::decay<_Tp>::type, void(boost::system::error_code, int)>::return_type async_do_something(CompletionToken&&) [with CompletionToken = boost::asio::basic_yield_context; typename boost::asio::async_result<typename std::decay<_Tp>::type, void(boost::system::error_code, int)>::return_type = int]’: main.cpp:38:38: required from here main.cpp:16:59: error: ‘struct boost::asio::async_completion<boost::asio::basic_yield_context, void(boost::system::error_code, int)>’ has no member named ‘completion_handler’; did you mean ‘completion_handler_type’? 16 | boost::async(boost::launch::async, [handler = completion.completion_handler]() mutable | ~~~^~~~~~ | completion_handler_type main.cpp:32:27: error: ‘class boost::asio::async_result<boost::asio::basic_yield_context, void(boost::system::error_code, int)>’ has no member named ‘get’ 32 | return completion.result.get();

liuaifu commented 1 year ago

Someone has already helped to solve it, please refer to: https://stackoverflow.com/questions/75705648/no-type-named-completion-handler-type-in-class-boostasioasync-result