Boost logo

Boost :

From: Kevlin Henney (kevlin_at_[hidden])
Date: 2003-03-22 12:39:06


In message <1fe801c2f08e$dabfcb60$8d6c6f50_at_pc>, Terje Slettebø
<tslettebo_at_[hidden]> writes
>>From: "Kevlin Henney" <kevlin_at_[hidden]>
>
>> However, the decision as to whether this should be in the 'what' string
>> is perhaps one that can be revisited.
>
>Indeed. :)
>
>I wasn't sure what kind of interface to use for this, so I just made it part
>of the what() string.

I am not a great fan of embedding programmer-specific info in exception
text messages as it is unobtainable by the programmer except in a debug
situation -- the correctness of a program should not rely on debugging
:-> -- and such precision is of less use to other users.

>> It would be feasible to avoid any
>> allocation issues at all by leaving the human readable string as general
>> as it was before and adding type_info members that described the source
>> and target types.
>
>Yes. Since type_info objects can't be copied, one might instead store
>pointers or references to them.

Pointers would be better because, for better or for worse (mostly for
worse), standard exceptions support assignment as part of their
interface.

>This appears to need yet another inheritance
>layer, though, unless the virtual functions for accessing the type_info
>objects are made part of bad_lexical_cast.

Not necessarily. It would be reasonable to fold up the inheritance
again, and simply provide a two argument constructor and a concrete
implementation:

        class bad_lexical_cast : public std::bad_cast
        {
        public:
                bad_lexical_cast()
                : source(&typeid(void)), target(&typeid(void))
                {
                }
                bad_lexical_cast(
                        const std::type_info &source,
                        const std::type_info &target)
                : source(&source), target(&target)
                {
                }
                const std::type_info &source_type() const
                {
                        return *source;
                }
                const std::type_info &target_type() const
                {
                        return *target;
                }
                virtual const char *what() throw()
                {
                        return "bad_lexical_cast: ...";
                }
                virtual ~bad_lexical_cast() throw()
                {
                }
        private:
                const std::type_info *source;
                const std::type_info *target;
        };

The default constructor would be there for backward compatibility only
(in case anyone had decided to throw bad_lexical_cast in their own
code), but would be deprecated with immediate effect.

>> (2) Rollback the design to something closer to the original, ie a fixed-
>> string literal message as the result of calling 'what', and provide
>> supplementary information for handlers that care enough to catch a
>> bad_lexical_cast.
>
>I think this is a good solution, and it eliminates any throws from the
>exception. This may also be a more flexible solution, as the type_info
>objects may be used directly, in any custom error message.

Yes, this was my preferred option. My least favourite, which I didn't
list at all, was using an array.

Kevlin
____________________________________________________________

  Kevlin Henney phone: +44 117 942 2990
  mailto:kevlin_at_[hidden] mobile: +44 7801 073 508
  http://www.curbralan.com fax: +44 870 052 2289
  Curbralan: Consultancy + Training + Development + Review
____________________________________________________________


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk