std::future as a parameter to a function C++

8.3k views Asked by At

Consider following code

void printPromised(std::future<int> f)
{
    std::cout << f.get() << std::endl;
}

int main()
{
    printPromised(std::async(std::launch::async, [](){ return 8; })); // This works

    auto f = std::async(std::launch::async, [](){ return 8; });
    printPromised(f); // This won't work
}

It says "It is a deleted function". Why is that? Further I need to pass (share) the same promised result which std::async generated to multiple users. That means when someone calls the get() function, I need to pass the same result (I don't need to re generate the result using std::async if it is already generated) and also I need the blocking mechanism which std::future::get has.

2

There are 2 answers

7
Kerrek SB On BEST ANSWER

There can be only one future. You cannot have multiple copies of the same future. So you need to transfer ownership of the future to the function:

printPromised(std::move(f));
//            ^^^^^^^^^^^^

If you genuinely need shared access to a future, you can construct a shared_future from an ordinary future by calling the share() member function; this behaves similarly to a shared pointer:

auto sf = std::async(std::launch::async, [](){ return 8; }).share();

Now sf can be copied, and all copies wait for the same result, i.e. the wait() calls on all copies may block and will synchronize with the becoming-ready of the result.

0
Amith Chinthaka On

This is what I came up after this discussion.

#include <future>

typedef std::shared_future<int> SharedFutureInt;

struct Object 
{
    SharedFutureInt m_promised;
    bool isAssigned;

    Object() : isAssigned(false)
    {

    }

    SharedFutureInt getObjects()
    {
        if (isAssigned)
        {
            return m_promised;
        }

        m_promised = std::async(std::launch::async, [](){ return 8; });
        isAssigned = true;
        return m_promised;
    }
};

int main()
{
    Object obj;
    int a = obj.getObjects().get();
    int b = obj.getObjects().get();
    int c = obj.getObjects().get();

    return 0;
}