$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2006-08-08 18:28:54
Pavel Vozenilek wrote:
> "Emil Dotchevski" wrote:
>
>>>> http://article.gmane.org/gmane.comp.lib.boost.devel/146322
>>
>> 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?
>     }
> }
Yes, but what does dump_everything() look like?
The reason why this is important is that I can't imagine dump_everything 
being able to format a proper user message. The best it can do is dump stuff 
in a debug log, for example. Which begs the question, how do you format a 
proper message for the user? I think that the only way to do this is for the 
code that formats the message to *know*, for each class of exceptions, what 
info could be available. You can't parameterize this with a "visitor" 
interface. Or can you? That was my intention when I asked you for an 
example: what's in dump_everything?
>>> 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)) ....
What's wrong with
catch( This & )
{
}
catch( That & )
{
}
...
> 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.
You are trying to use value semantics with exception handling. Essentially, 
I don't see much of a difference between --
class foo: public exception { };
class bar: public exception { };
{
    ....
    throw foo();
}
...
catch( exception & e )
{
    if( dynamic_cast<foo *>(&e) )
        ....;
    if( dynamic_cast<bar *>(&e) )
        ....;
}
-- and --
int const foo = 1;
int const bar = 2;
{
    ....
    throw foo;
}
...
catch( int e )
{
    if( foo==e )
        ....;
    if( bar==e )
        ....;
}
Even if you use a map of some sort hidden behind a "visitor" interface, you 
are replacing the "catch-by-type" semantics of C++ with 
"catch-everything-and-examine-its-value" semantics. I don't think this is a 
good idea. I think we should stick to throwing unnamed temporaries, and 
catching by reference, based on the *type* of the exception object, not its 
*value*.
> 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.
[snip]
I understand what you mean, but I still think that this is a departure from 
the exception handling semantics intended by the C++ designers. This doesn't 
mean that it doesn't make sense, just pointing that out.
My personal opinion is that a list of ordered catch statements is the 
simplest way to get what you need. And it is directly supported by C++.
--Emil