为什么`packaged_task`没有扣除指南?

时间:2018-04-19 13:53:00

标签: c++ c++17 packaged-task

我天真地期待这个编译:

template <typename Func>
auto run(Func && func) {
    auto package = std::packaged_task{std::forward<Func>(func)}; // deduce the template args automatically (C++17)
    auto future = package.get_future();
    enqueue(std::packaged_task<void()>{std::move(package)}); // only works if packaged_task is <R()>, but ok
    return future;
}

对于说明:这可能来自线程池实现,enqueue()只是将参数排队等待在工作线程上执行。

然而,问题是packaged_task没有演绎指南,所以当然C ++ 17构造函数模板参数演绎失败了。

那么,为什么没有演绎指南?

1 个答案:

答案 0 :(得分:2)

三个std::future工厂都没有扣除指南

  • std::async是一个功能模板,因此不需要任何
  • std::promise必须从()推断,这是不明确的
  • std::packaged_task必须从潜在的重载函数(和operator() s)中推断出来,这是不明确的

请注意,packaged_task是错误的future-factory如果你有可调参数的参数,你只能将callable提供给它的构造函数。您的示例代码可能希望为auto future = std::async(std::forward<Args>(args)...);

你的例子真的应该像

template <typename> struct function_traits;

template <typename Ret, typename...Args>
struct function_traits<std::function<Ret(Args...)>
{
    using type = Ret(Args...);
}

template <typename Sig> 
using function_traits_t = function_traits<Sig>::type;

template <typename F>
auto run(F&& f) {
    using Sig = function_traits_t<decltype(std::function{f})>;
    auto package = std::packaged_task<Sig>{std::forward<F>(f)}; // fails to deduce the template args automatically
    auto future = package.get_future();
    enqueue(std::move(package)); // function can deduce
    return future;
}