有没有办法将std::async与std::experimental::future一起使用?

Is there a way to use std::async with std::experimental::future?

本文关键字:std future 一起 experimental async 有没有      更新时间:2023-10-16

注意:即使在 C++17 中,下面也是非法的!

#include <thread>
#include <future>
#include <experimental/future>
using namespace std;
int step1(experimental::future<int>)
{
return {};
}
int step2(experimental::future<int>)
{
return {};
}
int step3(experimental::future<int>)
{
return {};
}
int main()
{
return async([](){ return {}; })
.then(step1)
.then(step2)
.then(step3)
.get();
}

C++1Z提供两种类型的future

  1. std::future
  2. std:experimental::future

但是,std::async只返回std::future,因此上面的代码是非法的。如果std::async返回std:experimental::future,那就没问题了。

我的问题是:

有没有办法将std::asyncstd::experimental::future一起使用,使上面的代码在 C++1z 下合法?

没有办法将std::asyncstd::experimental::future一起使用,使上面的代码在 C++1z 下合法?

不。std::async返回一个std::future<T>尽管名称如此,但它与std::experimental::future<T>完全无关。

您必须编写自己的async版本,为您提供新的future。简化版本如下:

template <class F, class... Args,
class R = std::invoke_result_t<std::decay_t<F>, std::decay_t<Args>...>>
std::experimental::future<R> new_async(F&& f, Args&&... args)
{
std::experimental::promise<R> p;
auto fut = p.get_future();
std::thread thread([p=std::move(p), f=std::forward<F>(f),
args=std::tuple<std::decay_t<Args>...>(std::forward<Args>(args)...)] () mutable
{
try 
{
if constexpr(std::is_void_v<R>)
{
std::apply(std::move(f), std::move(args));
p.set_value();
}
else 
{
p.set_value(std::apply(std::move(f), std::move(args)));
}
}
catch(...)
{
p.set_exception(std::current_exception());
}
});
thread.detach();
return fut;
}

这不像async那样支持其他启动策略,但这只是一个开始。

看起来std::experimental::future具有与std::future相同的构造函数,因此应该可以从std::future构造std::experimental::future。但是,正如ildjarn所指出的那样,它实际上不是根据最新草案,因此在TS相应更改之前似乎没有办法做到这一点。