Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-10-21 10:29:19


From: "Greg Colvin" <gcolvin_at_[hidden]>
> I am basically in favor of Peter's design, except that I would
> prefer that reset() be defined as it is for auto_ptr, unless it
> truly damages the implementation. The std::auto_ptr is designed
> the way it is for simplicity of specification. Copy construction
> and assignment are defined as reset(a.release()), so reset() has
> to handle self-assignment properly.

Yes, this makes sense. But in our case neither copy construction nor
assignment are defined this way, since shared_ptr has no release() member.

> Perhaps this makes reset() a
> little more error prone, but I consider reset(), release(), and
> get() to be unfortunate historical accidents that should be used
> as little as possible.

I'm not that concerned about reset() errors; it's simply that making it
handle self-resets complicates both the precondition and the postcondition,
introducing a special case. It simply feels wrong, and doesn't buy us
anything.

In this case it complicates the specification instead of simplifying it. :-)

> I am also very much in favor of the shared_count design, but I am
> not sure we have the interface nailed down. So it would seem
> appropriate to put it in a details namespace for now, and compile
> in the associated constructors conditionally until we get enough
experience to be sure we have it right.

One thing we need to decide is whether shared_ptr should handle 'finalizers'
or not. Note that this doesn't affect shared_count, only the shared_ptr
interface.

For compilers that don't support member templates, I suggest that we
introduce a separate header (the convention is usually ob_shared_ptr.hpp,)
perhaps avaiable only through smart_ptr.hpp. This will make the code
considerably easier to read, since most of it is #ifdef-ed on this feature
(and I know that some programmers refuse to use shared_ptr because "the code
is too ugly.")

This 'compatibility' header will simply be a (possibly cleaned-up) version
of the current code and will not make use of shared_count.

> As for operator<, I still believe it is fundamentally wrong for
> a pointer type. I can accept it as a stopgap until the committee
> can work out the issues with std::less, but I'd prefer not to
> commit to the entire set of comparisons. I would like to see a
> boost::less (and boost::swap) that do the right thing for our
> smart pointers.

This is a very thorny issue. In my opinion neither operator< nor std::less
(which was originally devised as a function object version of operator<, no
more) is the "proper" ordering primitive. At the same time, I accept that
the current STL uses operator< (only; no >, <=, >=) for ordering and am
quite willing to define one when I need a type to be ordered. For instance,
my std::type_info* wrapper has operator<.

What convinced me that operator< is the right ordering primitive (in the
context of the current standard library design) was that I needed to make a

std::map<std::pair<typeinfo, typeinfo>, ...>

and a specialized std::less doesn't work here, while an operator< does. This
is not limited to std::pair, by the way; containers, as per table 65, also
have a 'proper' operator<, but no less<> specialization.

In any event, if we really have to reinvent the ordering primitive, I
suggest we _not_ name it boost::less (boost::before maybe.)

And of course, as a MSVC user, I prefer something that works over something
that doesn't work. I realize that this is not a very strong argument by
itself. :-)

--
Peter Dimov
Multi Media Ltd.

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