1

I was coding a for loop in C++11, where I needed to push back an async object onto a vector. I wanted to split the object initialization into two steps:

    std::vector<std::future<bool>> asyncThreads;

    for (int i = 0; i < processorCount; i++) {
        auto boundFunc = std::bind(&Foo::foo, this);
        auto asyncThread = std::async(std::launch::async, boundFunc)

        asyncThreads.push_back(asyncThread);
    }

Now I do realize that both boundFunc and asyncThread objects go out of scope at the end of the for loop (the push_back function should copy/move the values though), but then why does directly declaring the objects in the push_back call work? Like so:

    std::vector<std::future<bool>> asyncThreads;

    for (int i = 0; i < processorCount; i++) {
        asyncThreads.push_back(std::async(std::launch::async, std::bind(&Foo::foo, this)));
    }
user2793618
  • 305
  • 4
  • 10
  • 1
    The difference is `std::async(...)` is an rvalue expression while `asyncThread` is an lvalue expression. The first example tries to copy the `future` while the second moves it. Try using `std::move`. – François Andrieux Mar 22 '22 at 20:36
  • What's the difference between rvalue and lvalue? And how would I use the move function here? Sorry, still a bit new to c++ – user2793618 Mar 22 '22 at 20:36
  • You can take a look at [What is move semantics?](https://stackoverflow.com/questions/3106110/what-is-move-semantics). – François Andrieux Mar 22 '22 at 20:38
  • 1
    @user2793618 lvalue is simply almost everything that has a name (`int a = 5`), rvalue is value or expression that can occur only on the right side of `=` (literal strings, numbers etc) – complikator Mar 22 '22 at 20:41
  • @FrançoisAndrieux Thanks for the link, was informative. But why is it that copying the ```future``` object causes the code to fail, while moving it is ok? – user2793618 Mar 22 '22 at 21:24
  • 1
    @user2793618 A `std::future` is not copyable, but it is moveable. A future represents a resource that cannot be meaningfully shared, so its copy semantics are explicitly prevented to avoid errors. You can see [it's constructors here](https://en.cppreference.com/w/cpp/thread/future/future). The copy constructor (3) is `= delete` (disabled) while the move constructor (2) is provided. – François Andrieux Mar 22 '22 at 21:29

1 Answers1

1

A std::future object is not copyable, but moveable. So therefore, you must call move on the object to push it onto the vector.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
user2793618
  • 305
  • 4
  • 10