假设我有两个返回期货的函数:
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()
在此,我必须再次bar
致future<future<U>>
来回复{{1}},否则我会{{1}}。这是正确的方法吗?
答案 0 :(得分:6)
你想要的是一个单子。 std::future
几乎但不是一个单子,但缺乏正确组合功能的能力,正如你所注意到的那样。有关详细讨论,请参阅this blog post。
总结是,对于C ++ 17,已经为std::future
提出了另一种方法:next
或then
,它将把函数应用于未来的值一次它是可用的。例如,这大致相当于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程序员,并且意识到我可能已经把所有东西搞混了。我很高兴欢迎更正。