2

我天真地期待这个编译:

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 构造函数模板参数推导当然会失败。

那么,为什么没有扣除指南呢?

4

1 回答 1

2

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

  • std::async是一个函数模板,所以不需要任何
  • std::promise必须从 推断(),这是模棱两可的
  • std::packaged_task必须从可能重​​载的函数(和operator()s)中推断出来,这是模棱两可的

请注意,packaged_task如果您有可调用的参数,那么这是错误的未来工厂,您只将可调用提供给它的构造函数。您的示例代码可能想要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;
}
于 2018-04-19T15:04:24.670 回答