|
Boost : |
From: Valentin Bonnard (Bonnard.V_at_[hidden])
Date: 1999-11-05 10:32:52
Beman Dawes wrote:
> 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:
>
> class Base {};
> class Derived : public Base {};
>
> int main()
> {
> Derived d;
> Derived& rd = d;
> Base& rb = implicit_cast<Base&>(rd);
>
> if ( &rd != &rb )
> cout << "oops\n";
>
> return 0;
> }
It's worse than a slicing problem: it's a reference
binding in a return statement to an automatic variable,
ie a dandling reference.
> Ivan suggests fixing this by changing the arg to pass-by-reference:
>
> template< typename Target, typename Source >
> inline Target implicit_cast( Source& s ) { return s; }
>
> Issue 3: Issue 1 and 2 interact. The proposed resolution for 2
> 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
I would say that it copies, not slices. This is ill-formed
anyway (as it should be).
-- Valentin Bonnard
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk