【问题标题】:Compilation problem with std::async using g++8 and c++20使用 g++8 和 c++20 的 std::async 编译问题
【发布时间】:2019-12-24 01:47:07
【问题描述】:

我正在尝试使用std::async。我已经写了这段代码

template<transport_type tt>
void stop_update_distances(const std::vector<stop>& stops, stop& from, const general_s& s, const osrm_machine& machine){
//...not important code...
}

void tt_map::update_distances(pqxx::connection& conn, const general_s& s,
    const osrm_machine& walk_machine, const osrm_machine& car_machine){

  std::vector<std::future<void>> futures;
  futures.reserve(stops.size());

  for(stop& from : stops){
    auto res = std::async(std::launch::async, stop_update_distances<CAR>, stops, from, s, car_machine);
    futures.push_back(res);          
  }

}

但是 g++8 给我返回了这个错误

src/lib/tt_map.cpp: In member function ‘void kp::mp::tt_map::update_distances(pqxx::connection&, const kp::general_s&, const kp::osrm_machine&, const kp::osrm_machine&)’:
src/lib/tt_map.cpp:383:108: error: no matching function for call to ‘async(std::launch, <unresolved overloaded function type>, std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&)’
           auto res = std::async(std::launch::async, stop_update_distances<CAR>, stops, from, s, car_machine);
                                                                                                            ^
In file included from src/lib/tt_map.cpp:11:
/usr/include/c++/8/future:1712:5: note: candidate: ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)’
     async(launch __policy, _Fn&& __fn, _Args&&... __args)
     ^~~~~
/usr/include/c++/8/future:1712:5: note:   template argument deduction/substitution failed:
/usr/include/c++/8/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = void (&)(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&); _Args = {std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&}]’:
src/lib/tt_map.cpp:383:108:   required from here
/usr/include/c++/8/future:1712:5: error: no type named ‘type’ in ‘class std::result_of<void (*(std::vector<kp::mp::stop>, kp::mp::stop, kp::general_s, kp::osrm_machine))(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&)>’
/usr/include/c++/8/future:1745:5: note: candidate: ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...)’
     async(_Fn&& __fn, _Args&&... __args)
     ^~~~~
/usr/include/c++/8/future:1745:5: note:   template argument deduction/substitution failed:
/usr/include/c++/8/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<typename std::decay<_Tp>::type(typename std::decay<_Args>::type ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {void (&)(const std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&), std::vector<kp::mp::stop, std::allocator<kp::mp::stop> >&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&}]’:
src/lib/tt_map.cpp:383:108:   required from here
/usr/include/c++/8/future:1745:5: error: no type named ‘type’ in ‘class std::result_of<std::launch(void (*)(const std::vector<kp::mp::stop>&, kp::mp::stop&, const kp::general_s&, const kp::osrm_machine&), std::vector<kp::mp::stop>, kp::mp::stop, kp::general_s, kp::osrm_machine)>’

我不太明白。

我遵循了cppreference.com 中的示例。即使它不起作用。

感谢您的任何提示,有什么问题。

【问题讨论】:

  • CAR是完整的类型吗?
  • @Swift-FridayPie CAR 是枚举的一部分。所以我认为,CAR是一个完整的类型。

标签: c++ c++11 templates g++ c++20


【解决方案1】:

std::thread 和类似的类默认复制它们的参数,并将它们按值传递给线程函数。这可能不是您想要的。编译器出错的具体原因是stop_update_distances通过非常量引用获取stop&amp; from参数,无法在那里传递临时副本。

如果不知道stop_update_distances 应该如何使用它的参数,很难说清楚,但我猜你可能想通过引用传递它们。您可以根据需要将它们包装在 std::refstd::cref 中。像这样的:

 auto res = std::async(
    std::launch::async,
    stop_update_distances<CAR>,
    std::cref(stops),
    std::ref(from),
    std::cref(s),
    std::cref(car_machine));

小心发出的生命周期和访问同步 - 您现在正在线程之间共享对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 2013-12-15
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    相关资源
    最近更新 更多