结合返回期货的功能

时间:2015-01-28 13:11:37

标签: c++ future

假设我有两个返回期货的函数:

std::future<T> foo(int);

std::future<U> bar(T const &);

我想将这两个函数组合成一个函数,该函数将int作为参数并返回std::future<U>。我应该怎么写这个函数?对于返回期货的函数,是否可以推广函数组合?

std::future<U> foobar1(int x)
{
  auto foo_x = foo(x);
  return bar(foo_x.get());
}

此功能将阻止,直到foo返回的未来完成,对吧?这显然不是我想要的。

std::future<U> foobar2(int x)
{
  return std::async([=]()
  {
    auto foo_x = foo(x);
    return bar(foo_x.get()).get();
  });
}

get()仅仅是为了bar

让它变成新的未来,对std::async返回的未来致电std::future<U> foobar3(int x) { return foo(x).then([](std::future<T> f) { return bar(f.get()).get(); }; } 感到愚蠢
get()

在此,我必须再次barfuture<future<U>>来回复{{1}},否则我会{{1}}。这是正确的方法吗?

1 个答案:

答案 0 :(得分:6)

你想要的是一个单子。 std::future几乎但不是一个单子,但缺乏正确组合功能的能力,正如你所注意到的那样。有关详细讨论,请参阅this blog post

总结是,对于C ++ 17,已经为std::future提出了另一种方法:nextthen,它将把函数应用于未来的值一次它是可用的。例如,这大致相当于Haskell中的bind(注意:不是std::bind)。

我们来看两个函数:

T foo(int);
U bar(T const &);

我们在这里有一个映射int -> T -> U,你想要的是将这个映射提升到int -> std::future<T> -> std::future<U>。这可能是:

int x = 2;
std::async([=](){return foo(x);}).then(bar);

then是一个自动将T -> U映射到std::future<T> -> std::future<U>的函数。

免责声明:我不是Haskell程序员,并且意识到我可能已经把所有东西搞混了。我很高兴欢迎更正。