Boost logo

Boost :

Subject: Re: [boost] scoped_ptr deleter
From: Howard Hinnant (howard.hinnant_at_[hidden])
Date: 2009-09-16 11:47:29

I've been lurking on this thread for awhile now, and as a person who
is very familiar with the design and use of single-ownership smart
pointer with custom-deleter capability, I figured it was time to throw
my two cents in...

I find custom deleters handy with single-ownership even when I'm not
trying to move them out of scope. I usually use:

const unique_ptr<MyClass, MyDeleter<A>> p(...);

The const qualifier on the unique_ptr renders the unique_ptr to be
practically the same thing as scoped_ptr. It will take a const_cast
for this animal to transfer the ownership out of the scope.

I've also found that sometimes I'll start with a same-scope use, but
during refactoring, learn that I want to move the smart pointer
creation into a factory function (for reuse in several places). When
I do that, it is handy to not have to change smart pointer types
(besides dropping the const qualifier if I used that).

I've also found support for statefull deleters quite necessary (as
opposed to just handling stateless deleters). The proposed code:

template<class T,
class D = boost::checked_deleter<T> > // first patch line
class scoped_ptr
// ...

      // ...
      deleter()(ptr); // second patch line, instead of

does not handle statefull deleters. If this community does decide to
put a custom deleter into scoped_ptr (and I am ambivalent on that
decision), then I strongly encourage the designers of this patch to
mimic the custom deleter of unique_ptr. The latest specification of
it can be found here:

(search for "[unique.ptr]")

And here is a more readable link in tutorial form which hits the

(and includes a C++03 emulation).

The basic layout would look like:

template<class T,
class D = boost::checked_deleter<T> > // checked_deleter<T[]> should
be partially specialized to handle arrays
class scoped_ptr
     typedef typename details::compute_pointer<T, D>::type pointer;
     tuple<pointer, D> ptr_;

Until tuple is rewritten with the empty member optimization, you'll
want to use compressed_pair<pointer, D> instead.

The "compute_pointer" business defaults to T* unless D::pointer
exists, in which case pointer is D::pointer. This supports putting
this smart pointer in shared memory. Allocators, which are a common
use case, often have this nested type, and sometimes, it is not a raw

Storing the D as shown above will:

1. Optimize away the space for it when D is empty.
2. Support function pointer types.
3. Support non-empty (statefull) Ds.

I also recommend supporting lvalue-reference D types. This is very
handy when dealing with a stateful D that you don't want to move or
copy (say because it is a data member of the enclosing class). Such
support will probably come for free in C++0x, but requires a little
extra work in C++03 to avoid the reference-to-reference situation.

I also recommend deleter accessors which return *references* to the

    D& get_deleter();
    const D& get_deleter() const;

It is not uncommon to need access to the actual stored deleter (not a
copy of it) during the lifetime of the smart pointer (I needed this
just yesterday in code I was writing). This is used to change the
state of the deleter which alters the behavior the deallocation
process (e.g. do (or don't) destruct a certain field in the held

And you'll want scoped_ptr constructors which accept a deleter (to
initialize its state). And you'll want to disable the constructors
which don't take a deleter when D is a pointer or reference type (lest
it be null).

scoped_ptr<A[]> could be a nice synonym for scoped_array<A> if
checked_deleter is specialized for T[]. It is nothing more (or less)
than a nice, easy to remember name for the array variant of the smart

When you get done, you will have reinvented all of the const parts of
unique_ptr (which has several years of refinement under its belt by
now). I don't necessarily discourage that as it is a very educational


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