As stated in the std::future constructor:
Objects built by default are invalid
It just means calling the default constructor for the object, for example:
std::future<int> f;
This will invoke constructor # 1, which states:
The default constructor. Creates std :: future with no shared state. After building valid() == false .
As for the other part:
(if no transfer of the actual future is assigned)
This means that the move constructor ( future( future&& other ) # 2) will be called, which says:
Move constructor. Creates std :: future with shared status; others use move semantics. After building other.valid() == false .
In principle, the state of other in this constructor is carried over to this . This means that if other.valid() == true , then after returning the constructor, the other.valid() will be false , and this.valid() will be true . If other.valid() were false , then both ends would be false .
std::future<int> fut; // fut.valid() == false, default constructor std::future<int> valid_fut = std::async(std::launch::async, [](){ return 42; }); // obtain a valid std::future.. // valid_fut.valid() == true here //now move valid_fut into new_fut std::future<int> new_fut(std::move(valid_fut)); // new_fut.valid() == true // valid_fut.valid() == false
Summarizing:
Calling the default constructor for std::future will result in valid() == false . Always.
Calling the move constructor for std::future will result in valid() == true only if other.valid() was true before moving from it. False otherwise.
source share