std::async 对比 std::promise

std::async vs std::promise

我必须将 getter 函数包装到 std::future 对象中。
std::function<String (String)> -> std::function<std::future<String> (String)>

如此简单的问题,最好/最快的方法是什么?

这是我想到的两个选项。

我有一个功能:

std::function<String (String)> getter;

然后使用 std::promise:

包装它
std::function<std::future<String> (String)> binding = [getter](String context) {
    std::promise<String> p;
    p.set_value(getter(contex));
    return p.get_future();
};

或使用std::async:

std::function<std::future<String> (String)> binding = [getter](String context) {
    return std::async(std::launch::deferred, getter, contex);
};

正确答案是自己写 make_ready_future(直接从 std::experimantal 中写出来)。 std::promise 是我所知道的产生现成未来的唯一方法:async 产生非现成未来。

这需要一个值,并产生该值的未来,其中包含一些涉及引用包装器的奇特内容(您可以选择跳过)。

存在将其添加到 C++1z 中的提议,因此通过基于其接口构建您自己的版本,您可以使您的代码半符合未来要求。另外,作为一个经过审核的设计,它会比你自己的设计更糟糕。

写完后:

template<class F>
auto futuristic_wrapper( F&& f ) {
  return [f=std::forward<F>(f)](auto&&...args){
    return make_ready_future( f( decltype(args)(args)... ) );
  };
}

在 C++11 中你必须写一个 class 来替换 lambda:

template<class F>
struct futurize {
  F f;
  template<class...Args>
  operator()(Args&&...args)const->
  delctype(make_ready_future(f(std::forward<Args>(args)...)))
  { return make_ready_future(f(std::forward<Args>(args)...)); }
};
template<class F>
auto futuristic_wrapper( F&& f )->
futurize< typename std::decay_t<F>::type >
{
  return {std::forward<F>(f)};
}

这很烦人,但主要是机械转换。

这实际上不会产生 std::function< future<R>(Args...) >,但它会 return 可以转换成那个。如果我们根本不需要,则无需键入擦除。

你可以把你从 std::experimantal 偷来的 "your own version of to-be-standardized stuff" 放在像 notstd 这样的命名空间中。始终将它与 notstd:: 一起使用(永远不要 using namespace notstd;,而不是 using notstd::make_ready_future;,因为当将类型添加到 std 时,风险行为会发生变化),以便以后的用户清楚这是不是这些对象的标准版本。