std::promise<int> p1;
auto f = p1.get_future();
{
std::promise<int> p2(std::move(pr));
}
bool valid = f.valid(); // true
f.wait(); // does not throw, or fail, but returns immediately
f.get(); // throws an exception
Is there any way to check if a future is going to throw before calling get
? I hoped valid
would check... I'm not really sure how to get valid
to return false. Destroying the promise
without setting a value doesn't do it.
Is there any way to check if a future is going to throw before calling get?
No, as that would be somehow equal to receive the value stored in the future.
I hoped valid would check... I'm not really sure how to get valid to return false.
Valid will return true if the future refers to a shared state which can only be created by std::async
, std::packaged_task
or std::promise
. A counterexample would be a default constructed std::future
. Valid will also be false once you have called get
or share
on a valid(valid == true) future once.
Calling any other function than valid
or the move-assignment operator on an invalid(valid == false) future is UB.
Destroying the promise without setting a value doesn't do it.
No, that as mentioned above is not the point of valid, as the future still refers to shared state just that the other side - the promise - wasn't fulfilled. If on destruction of a promise no value or exception was set, an exception to indicate the broken promise is set.
Is there any way to check if a future is going to throw before calling get?
Your question is equivalent to:
Is there any way to check if a function is going to throw before calling it?
The answer to both questions is, in general, no.
Consider:
int func_that_might_throw()
{
if (rand() % 2)
throw 1;
return 0;
}
std::future<int> f = std::async(&func_that_might_throw);
int result = f.get();
The async
call could return a deferred function, in which case the function doesn't even run until you call get()
, so in general there is no way to tell in advance whether the result will be a value or an exception. (You can detect a deferred function by calling f.wait_for(std::chrono::seconds(0))
, but async
might not return a deferred function, and in that case the function could still be running asynchronously when you try to check if it has a stored exception, so you'd have to check if it's ready and has a stored exception, so checking just gets very messy.)
A valid future
with a shared state that is ready has a result, which is either a value or an exception. Both are valid results. If you don't want to handle exceptions then you should ensure an exception is not set in the shared state in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With