
Hi, I often find myself wanting a generic way to catch and process exceptions. For example, imaging having to export "C" interface from a C++ library. You would create a bunch of extern "C" functions that would invoke the right C++ code. One of the things that needs to be done in every such function is to catch and process all exceptions. Most of the exceptions-handling code would look the same or very similar (the same list of exceptions to catch, same way to handle given exception types). C++ to C is not the only place where you'd need this. Most of the module boundaries might want to trap exceptions. The first thing that developers do in these cases is they start generalizing the handling part. I.e., you'd create a separate function/functor that would handle an exception of a certain kind. Unfortunately it still leaves you with a barage of try/catch() statements in every function that doesn't want to leak exceptions. This creates not only the unpleasant look of a lot of catches (one might argue this point), but it creates a lot of repetition - you need to create catch statement for every exception you want to handle. It would be nice if I could assemble all the exceptions I want to handle (honoring their order) and the way to handle them in one single place under a single object. And then invoke that object on all functions that need to be called. I recently took a crack at this task and came up with a generic way to trap exception. Here's a brief API: trap_exceptions(<list-of-exception-handlers>); The previous line would create a callable object. The parameters are a variable number of exceptions handlers that could be either function pointers, references to functions or functors. One thing they have in common though is the signature: the signature should be "void(T)", where T is the type of the exception that the handler will handle. This "T" type is what the trap_exceptions-created callable object will use in the "catch" statements. Other important notes: the order of handlers is important as this will be the order of "catch" statements (i.e., trap_exceptions(HandleBase, HandleDerived) will hide all Derived exceptions). Whether the exception is caught by reference or by value is also controlled by the handler's signature. Signature "void()" means catch all exceptions indiscriminately. Specifying an empty parameter list will also mean to catch all exceptions indiscriminately. The result of the trap_exceptions call can be assigned to a variable: auto ex_trap = trap_exceptions(HandleEx1, HandleEx2, HandleEx3); //BOOST_AUTO can be used too. And I think it will be possible to use //it without registering HandleEx1 etc.) This object can now be used on multiple functions of any arity and any return type. Functors are supported too. ex_trap(func1); //will create a delayed-call object that upon invocation will call func1 and catch exceptions Ex1, Ex2 and Ex3 So, if func1 has signature int(int, char*, float), then ex_trap(func1)(1, "abc", .5); will call function func1 with the given set of arguments and catch afore-mentioned exceptions. The return type undergoes a significant transformation though. Since the return from this delayed function call now returns more information than before (the additional part being whether an exception has been thrown or not), this additional information is conveyed through the use of boost::optional. In the case of ex_trap+func1, the result will be boost::optional<int>. Functions/functors returning void have a special treatment though since unfortunately it's illegal to instantiate boost::optional<void>. For functions that return void, the return type of the delayed call will be a simple bool. There are some return types that have a special value that indicates "error" and could be used to indicate that an exception occured. In this case, just for convenience purposes, it'll be possible to specify this value and the return type will become the return type of the inner function, not optional<T>. I.e: //Let's say that -1 can be used to indicate that an exception has //occured, then ex_trap(func1, -1)(1, "abc", .5);//will have a return type of int. //-1 will be returned if an exception has been thrown and now all places that had return func1(1, "abc", .5); could simply be replaced with return ex_trap(func1, -1)(1, "abc", .5); //without using boost::optional I think one other use of this functionality can be in functional-style programming in C++. While it's trivial to convert syntactic constructs like "if", "while", "switch", and "for" to functional representations (i.e. if_(f1(), f2(), f3()); which means if (f1()) f2(); else f3(); ), it's a lot harder to create a functional representation of try/catch construct. trap_exceptions is an attempt at that. To illustrate that point more, say we have a tuple (or a fusion-like container) which contains a collection of functions/functors. Using fusion::transform it's possible to add certain qualities to these functions. With trap_exceptions, it'll be possible to add a "no exception leak" quality to this set of functions. Do you think a functionality like that will be useful for boost? Any comments are appreciated. Thanks, Andy. P.S. Currently I implemented this functionality in terms of C++0x. But I think it should be possible to use Boost to make it C++03 compatible.