std::async vs std::promise

std::async vs std::promise

本文关键字:std promise async vs      更新时间:2023-10-16

我必须将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 中,您必须编写一个类来替换 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时风险行为会发生变化(,以便以后的用户清楚这不是这些对象的标准版本。