Boost logo

Boost :

From: Greg Colvin (gcolvin_at_[hidden])
Date: 2001-09-04 10:41:55

From: David Abrahams <david.abrahams_at_[hidden]>
> From: "Greg Colvin" <gcolvin_at_[hidden]>
> > > Taking a step back, we can come up with any number of designs, but shouldn't
> > > we talk about what the designs should accomplish first?
> >
> > We have been, but further discussion is welcome.
> >
> > What I'm not trying to accomplish is to parameterize shared_ptr to
> > generate a large family of related classes. That is a bigger project
> > that should probably start fresh, and which will indeed require a
> > clear delineation of a family of Pointer concepts.
> Agreed. That's what I think we should do. I don't think that mutating
> shared_ptr a little bit just to satisfy one person's needs is the way to go.
> It is a relatively simple class, and should remain so.
> > What I am trying to do is pull together the discussions and experimental
> > code and feature requests built up over the years into a new version of
> > shared_ptr (and shared_array). The desiderata for me are:
> >
> > 1) Shared_ptr remains one class, with one interface and one semantics.
> > Libraries should be able to use shared_ptr as a common means of
> > communication without needing to templatize their interfaces by
> > (smart) pointer type.
> I don't understand the 2nd sentence above.

For a policy-based class like

    template<typename T, class Policy> class shared_ptr;

every choice of Policy creates a different class. So you can't write
interfaces that simply return or accept shared_ptr<T>

    void MyBase::GimmeOne(shared_ptr<MyBase>);

but have to either templatize

    template<class Policy>
    void MyBase::GimmeOne(shared_ptr<MyBase,Policy>);

or choose in advance which Policy you will support. For many programs
this is no big deal, but for others it is.

However, if you templatize the constructor, e.g.

    template<class Policy> shared_ptr(T*);

then choosing different policies does not change the type of shared_ptr.

So the space I am exploring is the range of variations that can be
supported in this way, and how simple can the interface be.

> > 2) It should be possible for users to easily customize the deletion
> > function for objects that are not created with operator new. For
> > example the many, many C interfaces that manage resouces with a pair
> > of pointer-returning functions for acquistion and release. Peter's
> > code has an implementation of this idea.
> Good.
> > 3) It should be possible to use shared_ptr with no risk of undefined
> > behavior, although for historical reasons some unsafe functions may
> > remain, such as construction and reset from raw pointers. These
> > functions proven to be a source of difficulty and error. Right
> > now I am leaning towards a static create() function with varying
> > numbers of parameters, initially faked with a large number of
> > create functions, but perhaps done right in the future with a
> > language extension.
> OK.
> > 4) It should be possible for the skilled user to modify the underlying
> > implementation to make some performance and safety trade-offs
> > with out affecting the interface. The current idea is to expose
> > the underlying counter object for customization, but it isn't
> > clear whether that will prove useful enough to be worth the price.
> My only problem with all this is that while you're trying to stretch what is
> currently a very simple class to cover many more bases, it's clear that it's
> not going to cover /my/ base the way a policy-based smart pointer would. I
> suspect that's going to be true of quite a few people.

Yes, that is the danger. Of course even a policy-based smart pointer
might fail to cover your base, or someone else's. It seems that the
more one cares about the precise details of implementation the less
likely it is that the pre-wired policies will meet your needs.

> IMO, simple things should be kept simple. To handle more complicated jobs, a
> new design is in order. This is especially true if you envision that
> "skilled" users will actually have to modify the source code of shared_ptr
> for their own needs. I consider myself somewhat skilled, and whatever skill
> I have contributes to this fact: I would rather write a new policy-based
> smart pointer than generate even one redundant copy of boost's shared_ptr
> code.

No, you would not need to modify shared_ptr source code, just plug in
your own by whatever means is provided.

Simplicity is a virtue, as ever.

> > I am also aware of the need, over the next year, to get a version of
> > shared_ptr ready for the C++ committee. So it is important to keep
> > the interface clean, and the design such that the more advanced
> > features can be dropped or modified by the committee without disturbing
> > the core functionality. In particular, doing (4) will probably reveal
> > more implementation detail than is appropriate for a standard class.
> I think you should seriously consider floating the current design without
> modification, or possibly with the addition of static create functions. It
> works!

Yes, it does. I think 1 and 3 above are worth presenting to the committee,
and that 2 and 4 are worth considering. I also have no trouble with the
Boost version have features that are not in the standard version.

Boost list run by bdawes at, gregod at, cpdaniel at, john at