Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2003-02-03 14:32:01


Thanks Beman.

On Monday, February 3, 2003, at 12:50 PM, Beman Dawes wrote:

> At 09:46 PM 2/2/2003, Howard Hinnant wrote:
>
> >Could someone review the motivations for wanting an implicit
> conversion
> >to T* ? I'm failing to come up with any myself.
>
> It is useful when it is desirable for the smart pointer to mimic a
> built-in pointer as closely as possible.

Yup, just exploring where to draw that line between "as closely as
possible" and "too close".

> One case where that happens is when making extensive use of a
> third-party library which passes a lot of arguments as raw pointers.
> Writing p.get() a great deal tends to make code less readable.
>
> Another case is when trying to toughen up legacy code by replacing a
> raw pointer variable with a smart pointer. Changes are minimized if
> the smart pointer mimics a raw pointer closely.

I find this remarkably analogous to the operator const charT* issue
with early basic_string. We needed that operator for better
compatibility with legacy code using null-terminated char arrays, and
writing s.c_str() all over the place doesn't read as nice. But in the
end, the implicit conversion to const charT* was deemed too error prone
for basic_string.

> To me, a major benefit of a policy based design is to be able to
> accommodate a wide range of features, including those which find only
> limited use.
>
> If a policy based smart pointer can't accommodate a wide range of
> features, I start to wonder if the design itself is inflexible and
> flawed. That's why I worry a lot about whether a given PBSP design can
> handle apparently marginal uses.

That is a strong argument. On the other hand, should a policy be
provided for a configuration that is overly error prone or dangerous?
I think the answer may be yes, but only if there is sufficient
motivation (like a big performance increase). Otherwise, no. Why
needlessly expose your clients to a dangerous interface?

I don't really know on which side of that danger line the implicit
conversion to raw pointer falls.

If we were rebuilding basic_string today, would we want to provide at
least the option of operator const charT* ?

If we were rebuilding auto_ptr today, would we want to provide at least
the option of implicit conversion to raw pointer?

Too demonstrate the danger part, imagine converting this code from raw
pointer to smart_ptr:

void foo()
{
     T* p = ...;
     //...
     delete p;
}

Joe Coder comes in and changes the constructor, but forgets to change
the "destructor".

void foo()
{
     smart_ptr<T, ...> p(...);
     //...
     delete p;
}

This is a run time error if p implicitly converts to a T*, else it is a
compile time error.

-Howard


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