Intermediate Gotchas
The Future You Can Get Only Once
reading the answer consumes the handle
int main() {
std::promise<int> promise;
auto result = promise.get_future();
promise.set_value(42);
std::cout << result.get() << '\n';
try {
std::cout << result.get() << '\n';
} catch (const std::future_error& error) {
std::cout << error.what() << '\n';
}
}
Run it. Can the same std::future return its value twice?
Answer
The first get() leaves the future with no state. The second call is
undefined behavior; this output is typical, not guaranteed.
Why¶
std::future::get() retrieves the result and releases this future's association with its
shared state, leaving valid() false. Calling any member other than the destructor, move
assignment, share or valid on a future in that state is undefined behavior
([futures.unique.future]). The standard only recommends that implementations detect it
and throw std::future_error with future_errc::no_state; libstdc++ does, which is why
this run reports anything at all. Treat the message as typical — the wording is this
library's, and a conforming implementation need not throw. GCC emits no warning under
-Wall -Wextra.
The fix¶
Read the future once, then keep the ordinary value:
Use std::shared_future when several readers genuinely need the same result.
Takeaway: get() consumes a std::future; save the value or use shared_future.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo