从 T 创建 std::future 的最佳方式<T>

Best way to create a std::future<T> from a T

本文关键字:lt gt 方式 创建 std future 最佳      更新时间:2023-10-16

我正在使用std::future<T>来存储可选异步操作的结果。根据函数的参数,操作可以是异步的,也可以是同步的。在同步情况下,我有一个值,我想将其存储在future中。我该如何最好地做到这一点?

https://en.cppreference.com/w/cpp/thread/future 中给出的例子是:

  1. packaged_taskfuture
  2. async()future
  3. futurepromise

但是没有make_futurefuture构造函数也不允许从值创建已实现future。因此,我创建了一个帮助程序函数来执行此操作,方法是通过如下所示的promise

template <typename T>
std::future<T> make_future(T&& t)
{
std::promise<T> p;
p.set_value(std::forward<T>(t));
return p.get_future();
}

这是从T创建std::future<T>的有效方法吗?

有没有更好的方法从T创建std::future<T>

编辑:示例,缓存:

Foo readAndCacheFoo(int id);
std::future<Foo> readFooAsync(int id)
{
{
const lock_guard lock{cacheMutex};
if (id == cachedId)
{
return make_future(cachedFoo);
}
}
return std::async(readAndCacheFoo, id);
}

这很容易完成,但有点复杂:

template <typename T>
std::future<T> make_future(T&& t)
{
auto fun = [val=std::forward<T>(t)]() { return val; };
std::packaged_task<T()> task(std::move(fun));
auto future = task.get_future();
task();
return future;
}

请注意,std::futurepackaged_task应该共享内部状态,因此这应该是安全的

编辑: 实际上,您的代码似乎也是有效的,甚至更简单

这是从 T 创建 std::future 的有效方法吗?

是的,它是。

但是,我想说"make_future"可能不是最合适的名称。"future"类的整个想法是,它的值可能在未来准备就绪,而你的函数总是返回一个已经实现的未来。

嗯,这只是一个名字...阿法克,你的逻辑很好。

编辑: 关于make_ready_futuremake_exceptional_future职能,有一个C++建议。 P0159R0