mercredi 8 juin 2022

Is it still valid when the variable passed to `std::async` is out of scope?

Is the code snippet below legal? What worries me is when factorial is invoked the fut_num may be already out of scope.

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

//int factorial(std::future<int> fut) //works, because there is a move constructor
int factorial(std::future<int>&& fut)
{
    int res = 1;
    int num = fut.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::future<int> fut_num{prs.get_future()};
        vec.push_back(std::async(std::launch::async, factorial, std::move(fut_num)));
    }  //`fut_num` is out of range now.
    
    prs.set_value(5);

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

And the same question about similar code snippet:

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

//int factorial(std::future<int> fut) //works, because there is a move constructor
int factorial(std::future<int>& fut)
{
    int res = 1;
    int num = fut.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::future<int> fut_num{prs.get_future()};
        vec.push_back(std::async(std::launch::async, factorial, std::ref(fut_num)));
    }  //`fut_num` is out of range now.
    
    prs.set_value(5);

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

My two cents about these code snippets:

1.The former code snippet is legal, since std::async copies std::move(fut_num)(i.e. std::move(fut_num) is passed by value to std::async). So there is a local fut_num when fcatorical is called.

2.The latter one is illegal, since fut_num is passed as a reference to std::async. When fut_num is out of scope, it's illegal to call functions which uses fut_num.

Aucun commentaire:

Enregistrer un commentaire