
On 7/5/06, Emil Dotchevski <emildotchevski@hotmail.com> wrote:
But when you handle the exception, you shouldn't catch exception_info &, you should catch T (from your example). And now you need dynamic_cast to get to the exception_info sub-object.
Yeah... Now I'm still thinking of perhaps another way within the current C++ limits of how to be able to do that (get the exception_info sub-object, or at least a handle to it) without having to do a dynamic_cast.
Granted that the idea is that the exceptions themselves will be designed by me, and that I know what code will require what information, it sounds like a reasonable way of going about it -- compared to doing a dynamic_cast all the time, and the interface being not so clear and "developer friendly".
But that's far from granted! Consider this example:
<example snipped>
OK, you are the designer of the my_fread and my_fwrite functions, and the file_read_error and file_write_error exceptions they throw. How do you know that a user will use them in a copy operation? You can't provide for storing a source and target file name in the exception objects without knowing that, can you?
Yeah... I never thought of it that way though -- I think I've always just exposed all the possible information that the exception handlers will want to get (which I always realize is such a waste too) by throwing really "fat" exceptions. But even then, it now still seems inadequate without using a facility such as the exception lib.
This is why the exception lib is necessary, because the context information is really that: context information. It depends on the context in which the code that throws is being called, and is out of your control and beyond your knowledge. The idea is to always use the failed function template when throwing, even if you don't have info to add to the exception at the point of the throw. This way you enable higher stack loations to add context information by catching you as exception_info &.
Okay, now that makes sense. :)
I meant for general catch blocks, I didn't intend to say that the literal catch(...) {} blocks. Something like this:
<sample snipped> But by catching composite_exception &, you are really using value semantics to handle the exception. It's like sayng that you can always throw integer error codes, then catch( int ), and do a switch-case on the error code.
In C++, we use types (not values) to differentiate between the different types of errors. The exception lib does not violate this principle: the value semantics of class exception_info are not intended for figuring out how to respond to the exception. When you throw failed<foo>(), you would catch(foo &) (or any of its public base types) to handle the exception; the exception_info sub-object is there only to provide context information, such as file names or whatever else makes sense for the user to see.
Agreed. Now it's clearer to me. Thanks for the clarifications, they are very much appreciated. Now if there's only a way of bypassing dynamic_cast in this situation... -- Dean Michael C. Berris C/C++ Software Architect Orange and Bronze Software Labs http://3w-agility.blogspot.com/ http://cplusplus-soup.blogspot.com/ Mobile: +639287291459 Email: dean [at] orangeandbronze [dot] com