
"Emil Dotchevski" wrote:
Could you provide an example of using this functionality at the top level of an application?
int main() { try { .... run application } catch(boost::exception& e) { e.dump_everything(); // what happened? } } This can be only approximated with chain of catch handlers and manual printing of the data.
There should be also ability to support visitation of exception objects. Imagine situation:
try { .... } catch (boost::exception& e) { e << ....;
// now some exceptions could be handled // and some need to be passed up ????
I am not sure I understand what you mean by typeswitch. Can you illustrate your point with more code?
typeswitch: if (dynamic_cast<This>(e)) .... else if (dynamic_cast<That>(e)) .... A visitor solution: try { ... } catch (boost::exception& e) { e << ... my_visitor m; m.process(e); } Now the visitor will have a typelist of exceptions it does handle and will internally generate a chain of dynamic_casts to select the most appropriate visit() function to be called. My partial inspiration is chapter Visitor from Alexandrescu's Modern C++ Design but it is (IMHO) possible to avoid any modifications of the visited classes (the exceptions) for the cost of more processing on visitor side. It may look like: struct my_visitor : public exception_visitor < mpl::list < std::runtime_error, std::bad_alloc, my_exception
{ void visit(std::runtime_exception& e) { ... } void visit(std::bad:alloc& e) { .... throw; } void visit(my_exception& e) { ....throw new_exception(); } void visit(boost::exception& e) { .. catch all others ... } }; Internally the base class could generate internal functions overloaded for every type and also fill a vector with addresses of these functions. The process() would ten go through the vector to find the best fitting internal functions. The internal function will then call the specific visit(). The trick is to order the checks to place the leat classes first to test. Alexandresu has such a technique and MPL likely as well. It is somehow different way than what GOF do but it provides the same end result (less efficiently but with just a single static type known). /Pavel