|
Boost : |
From: Valentin Bonnard (Bonnard.V_at_[hidden])
Date: 1999-11-05 11:36:01
C. Green wrote:
>
> At 10:15 AM -0500 1999.11.05, Beman Dawes wrote:
> >Darin Adler wrote:
> >
> [Darin's comments on implicit conversions in implicit_cast]
>
> >But implicit_cast<> needs more than reactivating the warnings. There
> >are other issues. (For reference, the current definition is given:)
> >
> > template< typename Target, typename Source >
> > inline Target implicit_cast( Source s ) { return s; }
> >
> >Issue 1: Valentin Bonnard has pointed out the conversion should be
> >done at the argument, in case it requires an access privilege which
> >implicit_cast doesn't enjoy. I guess this would be formulated as:
> >
> > template< typename T >
> > inline T implicit_cast( T s ) { return s; }
> >
> >Issue 2: Ivan Johnson has pointed out a implicit_cast slicing
> >problem:
> >
> [snip]
> > Derived d;
> > Derived& rd = d;
> > Base& rb = implicit_cast<Base&>(rd);
>
> I assume this must be for the first (two-typename template func), because
> the second one (single typename) will work fine here too.
>
> > if ( &rd != &rb )
> > cout << "oops\n";
> [snip]
> >Issue 3: Issue 1 and 2 interact. The proposed resolution for 2
> >[take Source& instead of plain Source] doesn't fix 1. The proposed
> >solution for 1 also fixes 2 for the example given, but silently
> >slices if the template parameter is omitted:
> >
> > Base& rb = implicit_cast(rd); // slices
>
> First, let's assume you show conforming code that compiles:
>
> Base const& rb = implicit_cast(rd);
>
> In other words, this bug is not caught. implicit_cast without a
> specification of the destination type is meaningless.
>
> >Anyone have a resolution that solves all three issues?
>
> template<typename T>
> struct mirror_type {
> typedef T type;
> };
>
> template<typename T>
> inline T implicit_cast( typename mirror_type<T>::type t ) {
> return t;
> }
>
> Will this work?
Oups ! yes !
> Side comment, implicit_cast seems to break code that casts to a const ref type:
>
> int const& ir = 1.0; // OK - temp int lives as long as ir lives
> int j = ir; // OK
>
> int const& ir2 = implicit_cast<int const&> (1.0); // temp destroyed at
> EOS, right?
Yes
> int j2 = ir2; // undefined
Yes
> This can be safe if no temp is generated, but how do we know that one is
> not being generated? (user-defined conversions, built-in conversion like
> above)
If implicit_cast cannot be used on references types, it just
isn't a general purpose implicit cast anymore and shouldn't
be called implicit_cast.
-- Valentin Bonnard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk