std :: async vs std :: promise

时间:2015-03-24 15:51:12

标签: c++ c++11 lambda future

我必须将一个getter函数包装到std::future对象中 std::function<String (String)> - &gt; 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);
};

1 个答案:

答案 0 :(得分:4)

正确的答案是编写自己的make_ready_futurestd::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中,您必须编写一个类来替换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...) >,但会返回可兑换的内容。如果我们不需要,就不需要输入擦除。

您可以在std::experimantal这样的名称空间中从notstd窃取“您自己的标准化内容”。始终将其与notstd::(从不using namespace notstd;,而不是using notstd::make_ready_future;一起使用,因为当类型添加到std时风险行为会发生变化,以便后来的用户明白这是不是这些对象的标准版本。