Search code examples
c++boost-asioc++-coroutine

Official asio::co_spawn example does not compile. How do you use co_spawn with io_context?


This sample here isn't compiling:

https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/example/cpp17/coroutines_ts/echo_server.cpp

The call to co_spawn does not recognize io_context as a valid executor.

co_spawn(io_context, listener(), detached);

Edit: Updated the description to point to the correct sample. The issue is occurring in both boost (1.75) and standalone asio (1.24).

cl.exe version is 19.34.31937

Compiler output:

C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): error C2665: 'boost::asio::any_io_executor::any_io_executor': no overloaded function could convert all the argument types
C:\Users\...\include\boost\asio\impl\any_io_executor.ipp(34,18): message : could be 'boost::asio::any_io_executor::any_io_executor(std::nullptr_t) noexcept'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : 'boost::asio::any_io_executor::any_io_executor(std::nullptr_t) noexcept': cannot convert argument 1 from 'const OtherExecutor' to 'std::nullptr_t'
        with
        [
            OtherExecutor=boost::asio::io_context::executor_type
        ]
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,11): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:\Users\...\include\boost\asio\any_io_executor.hpp(189,3): message : or       'boost::asio::any_io_executor::any_io_executor(std::nothrow_t,Executor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&!std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::is_valid_target_executor<Executor,boost::asio::any_io_executor::supportable_properties_type>,std::false_type>::type::value,int>::type) noexcept'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : 'boost::asio::any_io_executor::any_io_executor(std::nothrow_t,Executor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&!std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::is_valid_target_executor<Executor,boost::asio::any_io_executor::supportable_properties_type>,std::false_type>::type::value,int>::type) noexcept': expects 3 arguments - 1 provided
C:\Users\...\include\boost\asio\any_io_executor.hpp(167,3): message : or       'boost::asio::any_io_executor::any_io_executor(Executor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&!std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::is_valid_target_executor<Executor,boost::asio::any_io_executor::supportable_properties_type>,std::false_type>::type::value,int>::type)'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : Failed to specialize function template 'boost::asio::any_io_executor::any_io_executor(Executor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&!std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::is_valid_target_executor<Executor,boost::asio::any_io_executor::supportable_properties_type>,std::false_type>::type::value,int>::type)'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : With the following template arguments:
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : 'Executor=OtherExecutor'
C:\Users\...\include\boost\asio\any_io_executor.hpp(134,3): message : or       'boost::asio::any_io_executor::any_io_executor(std::nothrow_t,OtherAnyExecutor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::supportable_properties<0,void (boost::asio::execution::context_as_t<boost::asio::execution_context &>,boost::asio::execution::detail::blocking::never_t<0>,boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>)>::is_valid_target<OtherAnyExecutor>,std::false_type>::type::value,int>::type) noexcept'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : 'boost::asio::any_io_executor::any_io_executor(std::nothrow_t,OtherAnyExecutor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::supportable_properties<0,void (boost::asio::execution::context_as_t<boost::asio::execution_context &>,boost::asio::execution::detail::blocking::never_t<0>,boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>)>::is_valid_target<OtherAnyExecutor>,std::false_type>::type::value,int>::type) noexcept': expects 3 arguments - 1 provided
C:\Users\...\include\boost\asio\any_io_executor.hpp(110,3): message : or       'boost::asio::any_io_executor::any_io_executor(OtherAnyExecutor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::supportable_properties<0,void (boost::asio::execution::context_as_t<boost::asio::execution_context &>,boost::asio::execution::detail::blocking::never_t<0>,boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>)>::is_valid_target<OtherAnyExecutor>,std::false_type>::type::value,int>::type)'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : Failed to specialize function template 'boost::asio::any_io_executor::any_io_executor(OtherAnyExecutor,constraint<std::conditional<!std::is_same<OtherAnyExecutor,boost::asio::any_io_executor>::value&&std::is_base_of<boost::asio::execution::detail::any_executor_base,Executor>::value,boost::asio::execution::detail::supportable_properties<0,void (boost::asio::execution::context_as_t<boost::asio::execution_context &>,boost::asio::execution::detail::blocking::never_t<0>,boost::asio::execution::prefer_only<boost::asio::execution::detail::blocking::possibly_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::tracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::outstanding_work::untracked_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::fork_t<0>>,boost::asio::execution::prefer_only<boost::asio::execution::detail::relationship::continuation_t<0>>)>::is_valid_target<OtherAnyExecutor>,std::false_type>::type::value,int>::type)'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : With the following template arguments:
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : 'OtherAnyExecutor=OtherExecutor'
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(255,10): message : while trying to match the argument list '(const OtherExecutor)'
        with
        [
            OtherExecutor=boost::asio::io_context::executor_type
        ]
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(378,1): message : see reference to function template instantiation 'boost::asio::detail::initiate_co_spawn<boost::asio::any_io_executor>::initiate_co_spawn<Executor>(const OtherExecutor &)' being compiled
        with
        [
            Executor=boost::asio::io_context::executor_type,
            OtherExecutor=boost::asio::io_context::executor_type
        ]
C:\Users\...\include\boost\asio\impl\co_spawn.hpp(375,3): message : see reference to function template instantiation 'boost::asio::detail::initiate_co_spawn<boost::asio::any_io_executor>::initiate_co_spawn<Executor>(const OtherExecutor &)' being compiled
        with
        [
            Executor=boost::asio::io_context::executor_type,
            OtherExecutor=boost::asio::io_context::executor_type
        ]
C:\Users\...\Main\asio_test\asio_test.cpp(298,20): message : see reference to function template instantiation 'void boost::asio::co_spawn<boost::asio::io_context::executor_type,main::<lambda_,const boost::asio::detached_t&>(const Executor &,F &&,CompletionToken,int)' being compiled
        with
        [
            Executor=boost::asio::io_context::executor_type,
            F=main::<lambda_,
            CompletionToken=const boost::asio::detached_t &
        ]

Solution

  • This was caused by incorrect compiler options in visual studio.

    Conformance mode: /permissive was set.

    After changing this to /permissive- the sample compiles.

    https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170