John
John

Reputation: 3534

Is it legal to pass `std::shared_future` as a reference to functions?

Passing std::shared_future by value is legal, since std::shared_future is copyable.

#include <future>
#include <vector>
#include <iostream>

int factorial(std::shared_future<int> sf)
{
    int res = 1;
    int num = sf.get();

    for(int i=num; i>1; i--)
    {
        res *= i;
    }

    return res;
}

int main()
{
    std::promise<int> prs;
    std::vector<std::future<int>> vec;


    std::shared_future<int> sf{prs.get_future()};
    for(int i=0; i<10; i++)
    {
        vec.push_back(std::async(std::launch::async, factorial, sf));
    }  
    
    prs.set_value(5);

    for(auto& fut: vec)
    {
        std::cout << fut.get() << std::endl;
    }
}

Is it legal to pass std::shared_future as a reference to functions?

#include <future>
#include <vector>
#include <iostream>

int factorial(std::shared_future<int>& sf)
{
    int res = 1;
    int num = sf.get();

    for(int i=num; i>1; i--)
    {
        res *= i;
    }

    return res;
}

int main()
{
    std::promise<int> prs;
    std::vector<std::future<int>> vec;


    std::shared_future<int> sf{prs.get_future()};
    for(int i=0; i<10; i++)
    {
        vec.push_back(std::async(std::launch::async, factorial, std::ref(sf)));
    }  

    prs.set_value(5);

    for(auto& fut: vec)
    {
        std::cout << fut.get() << std::endl;
    }
}

The code snippet compiles and seems work well. Could somebody shed some light on this mattter?

UPDATED:

For shared_ptr, many aspects need to be considered when choosing to passing as a reference or passing by value.

What about shared_future? How to make the choice?

Upvotes: 3

Views: 655

Answers (1)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123431

From cppreference:

Calling wait on the same std::shared_future from multiple threads is not safe; the intended use is for each thread that waits on the same shared state to have a copy of a std::shared_future.

A shared_future is already behaving like a "reference" to some shared state. However, its intended use is that each thread uses its own copy, such that they can call wait and other methods without getting into their way.

Upvotes: 1

Related Questions