I have a function that returns a std::future
. I have added a cache to the implementation, and I would like to optionally return a value immediately if it does not need to be recalculated.
How can I create an already-resolved future?
// Class declarations shortened to minimal example to communicate intent
class MyClass {
Cache m_cache;
std::future<int> foo(int arg);
}
class Cache {
std::optional<int> get(int arg);
}
std::future<int> MyClass::foo(int arg) {
if (auto res = m_cache.get(arg)) {
// *res is my result
return std::future(*res); // ????? Doesn't work
}
// If the cache misses, we need to calculate it
// Fire up the ol' thread pool and get to work
return std::launch(std::launch::async /* ommited for brevity */);
}
I'm targeting C++20.
Only std::async
, std::packaged_task
and std::promise
can create futures with new states.
std::promise
is the easiest way:
std::future<int> MyClass::foo(int arg) {
if (auto res = m_cache.get(arg)) {
// *res is my result
std::promise<int> p;
p.set_value(*res);
return p.get_future();
}
// If the cache misses, we need to calculate it
// Fire up the ol' thread pool and get to work
return std::launch(std::launch::async /* ommited for brevity */);
}
// Or with a helper function
template<typename T>
std::future<std::decay_t<T>> make_ready_future(T&& value) {
std::promise<std::decay_t<T>> p;
p.set_value(std::forward<T>(value));
return p.get_future();
}
std::future<int> MyClass::foo(int arg) {
if (auto res = m_cache.get(arg)) {
// *res is my result
return make_ready_future(*res);
}
// If the cache misses, we need to calculate it
// Fire up the ol' thread pool and get to work
return std::launch(std::launch::async /* ommited for brevity */);
}