假设我有两个返回期货的函数:
std::future<T> foo(int);
std::future<U> bar(T const &);
Run Code Online (Sandbox Code Playgroud)
我想将这两个函数组合成一个带有intas参数并返回a 的函数std::future<U>.我应该怎么写这个函数?对于返回期货的函数,是否可以推广函数组合?
std::future<U> foobar1(int x)
{
auto foo_x = foo(x);
return bar(foo_x.get());
}
Run Code Online (Sandbox Code Playgroud)
此函数将阻塞,直到返回的未来foo完成,对吧?这显然不是我想要的.
std::future<U> foobar2(int x)
{
return std::async([=]()
{
auto foo_x = foo(x);
return bar(foo_x.get()).get();
});
}
Run Code Online (Sandbox Code Playgroud)
如果只是为了让它变成一个新的未来,那么对于get()回归的未来感到愚蠢barstd::async
std::future<U> foobar3(int x)
{
return foo(x).then([](std::future<T> f)
{
return bar(f.get()).get();
};
}
Run Code Online (Sandbox Code Playgroud)
在这里,我必须再次呼吁get()将来回归,bar否则我会有一个future<future<U>>.这是正确的方法吗?
你想要的是一个单子.std::future几乎但不是一个单子,但缺乏正确组合功能的能力,如你所注意到的那样提升它们.有关此问题的详细讨论,请参阅此博客文章.
该摘要是用于C++ 17的另一种方法已被提议用于std::future:要么next或then这将需要的功能被应用到未来的值一旦它是可用的.这大致相当于bindHaskell中的例子(注意:不是std::bind).
我们来看两个函数:
T foo(int);
U bar(T const &);
Run Code Online (Sandbox Code Playgroud)
这里我们有一个映射int -> T -> U,你想要的是解除这个映射int -> std::future<T> -> std::future<U>.这看起来像是:
int x = 2;
std::async([=](){return foo(x);}).then(bar);
Run Code Online (Sandbox Code Playgroud)
哪里then是自动映射T -> U到的函数std::future<T> -> std::future<U>.
免责声明:我不是Haskell程序员,并且意识到我可能已经把所有东西搞混了.我很高兴欢迎更正.