From: Greg Colvin (gcolvin_at_[hidden])
Date: 2000-08-30 22:36:53


From: Greg Colvin <gcolvin_at_[hidden]>
> ...
> We've been considering an improvement to shared_ptr to
> add template constructors parameterized on a function
> or functor that does the deletion. We can arrange it
> so that type of shared_ptr(T*) is the same as the type
> of shared_ptr(T*,deleter), which might provide for the
> sort of polymorphism Thomas wants. I'll take this
> thread as motivation to write the idea up in more
> detail.

I can see I'm not going to have time for much detail,
and the code is not ready for prime time, so I'll say a
little now rather than delay any longer.

The motivating example is the desire to write code like
this:

   shared_ptr<FILE> p(fopen(name,mode),fclose);

The solution could look, in part, like this:

   template<typename T> class shared_ptr {
   public:
      explicit shared_ptr(T*=0);
      template<typename Disposer>
         explicit shared_ptr(T*,const Disposer&);
   ...

where Disposer can be either a function or a functor
that supports operator()(T*).

A nice thing about this solution for object-oriented
programming is that the type of Disposer does not affect
the type of shared_ptr. Another nice thing is that T
can be an incomplete type at the point of declaration
of shared_ptr<T>. The cost of this nicety is that
calling Disposer() will require a virtual function call,
and that some of the implementation of shared_ptr will
need to be moved out of the header file into a separate
source file.

The implementation details involve making sure that the
type of Disposer does not get exposed to clients, and
that no space is wasted for empty Disposer classes. I
am experimenting now with keeping the count and the
Disposer together as compressed_pair in a class derived
from an abstract base class with a virtual function for
calling the Disposer.

Note that this is a very tentative step into the large
smart pointer feature space that Beman has laid out.