
Felipe Magno de Almeida wrote:
People use interfaces to allow for different implementation strategies. But the only implementation possible for get_exception_info is to use dynamic_cast!
That is not the only reason. The implementation is just a detail from a user point of view, things that expose that implementation become a distraction to the user.
Are you saying that the user knows that the object returned by failed<T> derives from both T and exception info, yet is distracted by the fact that dynamic_cast can be used to go from T * to exception_info *? I'm not arguing that to have a function get_exception_info is unreasonable -- someone may have their reasons to define it. But IMO this is beyond the scope of the exception library.
Therefore, to me anyway, get_exception_info's purpose is to hide the dynamic_cast so I don't get emails like "why do you have a dynamic_cast as part of your interface". It's not part of the interface, it's part of C++. It does exactly what you need when you catch(T&) and want to see if you can get an exception_info *.
If a user has to use dynamic_cast to be able to use the library then it is part of the interface too, IMO.
The users also have to use "throw" to use the library, and indeed it makes sense to hide it in a function (or a macro) because someone might want to compile with exception handling disabled. Or to not throw if it's Friday the 13th. But this is beyond the scope of the exception library.
And asking why seems to me like a very reasonable question.
I'm not arguing that "why haven't you hidden the dynamic_cast in a function" is unreasonable question.
Now, using dynamic_cast to implement the library is not a problem, since it is not of my concern as a user.
Except that it is also reasonable for someone, after reading the documentation, to be puzzled why was it necessary to write get_exception_info when dynamic_cast is the only way it can be implemented.
As an example of good implementation hiding, boost::function uses void* all over the place, albeit its interface is as clean and straightforward as it can be. Even if void* is or isnt the only implementation possible.
There are many other examples that (correctly) hide implementation details behind an interface. There are many cases about which I'd agree that hiding a dynamic_cast behind an interface is necessary. Regards, Emil