Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to create an already-resolved future

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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 */);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading