|
Boost : |
From: Bill Wade (bill.wade_at_[hidden])
Date: 2000-07-21 16:25:44
> [From] Valentin Bonnard
> I see two possible uses for ES:
> [deleted]
A third possible use:
throw(A,B,bad_exception)
is a convenient shorthand for
try{ stuff_that_might_throw(); }
catch(A&){ throw; }
catch(B&){ throw; }
catch(bad_exception&){ throw; }
catch(...){ unexpected(); }
If you really do need to map all possible exceptions to a small set of
exceptions (say those exceptions that you know how to send via smoke signals
with an agreed-upon protocol), the notational convenience is handy.
// Interface from my vendor. I can't change this
struct foo_t
{
virtual result_t bar(arg_t) throw(A,B,...Z) = 0;
... Thirty other functions with similar interfaces ...
};
// Class I need to write.
struct my_foo_t: foo_t { result_t bar(arg_t) throw(A,C,E,...Y); };
// my_foo_t::bar is going to call functions that might throw anything
// If something not on my throw list is about to escape, I want to convert
// it to a default-constructed A.
// Copy constructors for result_t and arg_t never throw.
result_t my_foo_t::bar(arg_t arg) throw (A,C,E,...Y)
{
scoped_set_unexpected<A> x;
if(x.needs_recursion())
{
return bar(arg);
}
else
{
return ComputeResultButMightThrowAnything();
}
}
Writing the template class scoped_set_unexpected should be straightforward.
In the absence of throw specifications the implementation of my_foo_t::bar()
is much uglier and much more error prone. If the vendor was nice enough to
include bad_exception in foo_t::bar()'s throw list, and I decide to allow
bad_exception to escape from my bar(), the implementation of my bar()
becomes a trivial call to ComputeResultButMightThrowAnything().
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk