asio icon indicating copy to clipboard operation
asio copied to clipboard

make_parallel_group - no type named 'type' or has no member named ‘async_wait’

Open madkote opened this issue 1 month ago • 1 comments

hi all, I am trying to use make_parallel_group to execute tasks in parallel and await for results.

Code

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/experimental/awaitable_operators.hpp>
#include <boost/asio/experimental/parallel_group.hpp>
#include <boost/version.hpp>

boost::asio::awaitable<std::string> fetch_name(int id) {
    std::cout << "fetch_name: " << id << std::endl;
    co_await boost::asio::steady_timer(co_await boost::asio::this_coro::executor, std::chrono::milliseconds(id * 1000)).async_wait(boost::asio::use_awaitable);
    std::cout << "fetch_name: " << id << " done" << std::endl;
    co_return "name_" + std::to_string(id);
}

boost::asio::awaitable<void> coro_main() {
    std::cout << BOOST_LIB_VERSION << std::endl;
    co_await fetch_name(1);

    auto exec = co_await boost::asio::this_coro::executor;

    std::vector<boost::asio::awaitable<std::string>> tasks;    
    tasks.emplace_back(fetch_name(1));
    tasks.emplace_back(fetch_name(2));

    std::vector<std::string> results;

    /* with operator if tasks are known */
    using boost::asio::experimental::awaitable_operators::operator&&;
    auto [r1, r2] = co_await (
        fetch_name(1) &&
        fetch_name(2)
    );
    results.emplace_back(std::move(r1));
    results.emplace_back(std::move(r2));

    /* with group if tasks are un-known */
    // using op_type = decltype(fetch_name(3));
    // std::vector<op_type> ops;
    std::vector<boost::asio::awaitable<std::string>> ops;
    ops.push_back(fetch_name(3));
    ops.push_back(fetch_name(4));

    // TODO: ideally return results as vector?
    /* auto [r3, r4] = */co_await boost::asio::experimental::make_parallel_group(
        std::move(ops)
    ).async_wait(
        boost::asio::experimental::wait_for_all(),
        boost::asio::deferred /*boost::asio::use_awaitable*/);

    std::cout << std::endl << "--- example_one_strings ---" << std::endl;
    for (const auto& item : results) {
        std::cout << "example_one_strings: " << item << std::endl;
    }
    std::cout << "--- --- ---" << std::endl << std::endl;

    co_return;
}

int main() {
    boost::asio::io_context ioc;
    boost::asio::co_spawn(
        ioc,
        coro_main,
        boost::asio::detached
    );
    ioc.run();
}

Errors with boost 1.87 and gcc 13.3:

In file included from <source>:2:
In file included from /app/boost/include/boost/asio.hpp:20:
In file included from /app/boost/include/boost/asio/any_completion_executor.hpp:22:
In file included from /app/boost/include/boost/asio/execution.hpp:18:
In file included from /app/boost/include/boost/asio/execution/allocator.hpp:19:
/app/boost/include/boost/asio/detail/type_traits.hpp:143:1: error: no type named 'type' in 'boost::asio::result_of<boost::asio::awaitable<std::basic_string<char>> (boost::asio::detail::completion_signature_probe)>'
  143 | using result_of_t = typename result_of<T>::type;
      | ^~~~~
/app/boost/include/boost/asio/async_result.hpp:933:3: note: in instantiation of template type alias 'result_of_t' requested here
  933 |   result_of_t<T(Args..., detail::completion_signature_probe)>
      |   ^
/app/boost/include/boost/asio/async_result.hpp:940:1: note: in instantiation of template class 'boost::asio::completion_signature_of<boost::asio::awaitable<std::basic_string<char>>>' requested here
  940 | using completion_signature_of_t =
      | ^
/app/boost/include/boost/asio/experimental/parallel_group.hpp:316:7: note: in instantiation of template type alias 'completion_signature_of_t' requested here
  316 |       completion_signature_of_t<
      |       ^
<source>:43:35: note: in instantiation of template class 'boost::asio::experimental::ranged_parallel_group<std::vector<boost::asio::awaitable<std::basic_string<char>>>>' requested here
   43 |     /* auto [r3, r4] = */co_await boost::asio::experimental::make_parallel_group(
      |                                   ^
1 error generated.

Errors with boost 1.89 and gcc 13.3:

In file included from /home/madkote/cxx/boost_1_89_0/include/boost/asio/execution/allocator.hpp:19,
                 from /home/madkote/cxx/boost_1_89_0/include/boost/asio/execution.hpp:18,
                 from /home/madkote/cxx/boost_1_89_0/include/boost/asio/any_completion_executor.hpp:22,
                 from /home/madkote/cxx/boost_1_89_0/include/boost/asio.hpp:20,
                 from /home/madkote/example/main3.cpp:2:
/home/madkote/cxx/boost_1_89_0/include/boost/asio/detail/type_traits.hpp: In substitution of ‘template<class T> using boost::asio::result_of_t = typename boost::asio::result_of::type [with T = boost::asio::awaitable<std::__cxx11::basic_string<char> >(boost::asio::detail::completion_signature_probe)]’:
/home/madkote/cxx/boost_1_89_0/include/boost/asio/async_result.hpp:952:8:   required from ‘struct boost::asio::completion_signature_of<boost::asio::awaitable<std::__cxx11::basic_string<char> > >’
/home/madkote/cxx/boost_1_89_0/include/boost/asio/experimental/parallel_group.hpp:318:24:   required from ‘class boost::asio::experimental::ranged_parallel_group<std::vector<boost::asio::awaitable<std::__cxx11::basic_string<char> > >, std::allocator<void> >’
/home/madkote/example/main3.cpp:43:81:   required from here
/home/madkote/cxx/boost_1_89_0/include/boost/asio/detail/type_traits.hpp:143:7: error: no type named ‘type’ in ‘struct boost::asio::result_of<boost::asio::awaitable<std::__cxx11::basic_string<char> >(boost::asio::detail::completion_signature_probe)>’
  143 | using result_of_t = typename result_of<T>::type;
      |       ^~~~~~~~~~~
In file included from /home/madkote/cxx/boost_1_89_0/include/boost/asio/experimental/awaitable_operators.hpp:27,
                 from /home/madkote/example/main3.cpp:3:
/home/madkote/cxx/boost_1_89_0/include/boost/asio/experimental/parallel_group.hpp: In instantiation of ‘class boost::asio::experimental::ranged_parallel_group<std::vector<boost::asio::awaitable<std::__cxx11::basic_string<char> > >, std::allocator<void> >’:
/home/madkote/example/main3.cpp:43:81:   required from here
/home/madkote/cxx/boost_1_89_0/include/boost/asio/experimental/parallel_group.hpp:318:24: error: no type named ‘type’ in ‘struct boost::asio::completion_signature_of<boost::asio::awaitable<std::__cxx11::basic_string<char> > >’
  318 |       Allocator>::type signature;
      |                        ^~~~~~~~~
/home/madkote/example/main3.cpp: In function ‘boost::asio::awaitable<void, boost::asio::any_io_executor> coro_main()’:
/home/madkote/example/main3.cpp:45:7: error: ‘class boost::asio::experimental::ranged_parallel_group<std::vector<boost::asio::awaitable<std::__cxx11::basic_string<char> > >, std::allocator<void> >’ has no member named ‘async_wait’
   45 |     ).async_wait(
      |       ^~~~~~~~~~
gmake[2]: *** [example/CMakeFiles/gather.dir/build.make:76: example/gather/CMakeFiles/gather.dir/main3.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:149: example/CMakeFiles/gather.dir/all] Error 2
gmake: *** [Makefile:136: all] Error 2


I have tried various combinations, but non is working. Please any advice?

madkote avatar Nov 24 '25 16:11 madkote