std::optional<T> f() {
try { return it(); }
catch(...) {
clean_up();
return {};
}
}
Trivial. If you don't want to throw away the exception: T f() {
try { return it(); }
catch(...) {
clean_up();
throw;
}
}
But of course cleanup code belongs in a destructor, so nobody does that. In C++, we say T f() { return it(); }
and the responsible destructor does its job, either way.The try! macro didn't have that insight, and the first attempt to make a Try operator didn't either, but the current one does. This sort of experimentation is not available in practice to C++ but that would only slow it down a little, what prevents forward motion far more is that WG21 doesn't want to learn from other people's experiments.
C++ 23 gets std::expected which is, modulo IFNDR nonsense, a Result type. But C++ 23 doesn't have, and none of the further papers propose, a type analogous to ControlFlow.
I actually wondered how C++ 23 does the equivalent of Iterator::try_fold without ControlFlow, how do they express this idea? Did they use std::expected here as once Rust used Result ? The answer seems to just be "They don't" which I think gets to the heart of it.
A resumable, short-circuiting fold would be just as useful in C++ as it is in Rust, but it's easy to express nicely in Rust and doing so in C++ would insight anger from Exceptions purists, so that likely won't happen.
If you cannot figure it out, find someone to explain it to you, instead doubling down when your falsehood is pointed out.