Boost logo

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