Boost logo

Boost :

From: Daniel Wallin (dalwan01_at_[hidden])
Date: 2004-01-03 06:55:23


David B. Held wrote:
> "Daniel Wallin" <dalwan01_at_[hidden]> wrote in message
> news:3FF562C5.5050403_at_student.umu.se...
>
>>But even then smart_ptr<> is lacking the:
>>
>> const_pointer_type operator->() const
>> const_reference_type operator*() const
>> .. and maybe a templated reset().
>>
>>needed to propagate constness.
>
> <snip>
> But then, we aren't talking about a shallow copy pointer, so perhaps
> smart_ptr should support const propagation for certain policies.

Exactly.

>>Unfortunatly both the storage and ownership policies need to
>>capture the type of the pointee, meaning they both need to store
>>a function pointer.
>
>
> Well, this forced me to dig through shared_ptr<> some more, and
> now I understand what the default checked_deleter<> is all about.
> However, it seems to me that more deleters are being saved than
> is strictly necessary.
>
>
>>So we'd end up with a smart pointer that is much larger than
>>needed.
>
>
> Well, it depends entirely upon how the deleter is implemented.
> While thinking about solutions to this problem, I considered
> whether a static map/associative vector/hash map of deleters
> might be more efficient overall. After all, there will probably be
> many more pointers than there will be deleter types.

In the case of shared_ptr<>, this isn't possible since the deleter can
have state. Besides, map lookup + mutex will likely be much slower than
the deleter allocation which can be made arbitrarily fast with a custom
allocator.

Note though that in the case of value_ptr<> the deleter does not have
state, so it's just a function pointer. This goes for the cloner as
well.

   template<class T> class value_ptr
   {
       ...
       T* m_p;
       const detail::value_ptr_ops* m_fn;
   };

The two function pointers are stored in a statically allocated
value_ptr_ops which the value_ptr<> holds a pointer to. Very efficient.

   http://www.cs.umu.se/~ens01dwn/value_ptr.hpp, for details.

> I guess it
> comes down to a tradeoff in creation speed vs. size. And, of
> course, that could probably be controlled by a policy. ;)

Well that's not the issue though. I don't care about the extra pointer
introduced by the deleter and cloner functions. I do care about the
extra *unnecessary* pointer introduced by the fact that different
policies can't share state.

I'd even make a stretch and say that this is a general problem with
some policy based designs; somewhere along the line there will turn up
policies that need to share state, or suites of policies that can only
work together and should really be just one policy. Here are some
potential issues to think about:

   1. The assumption that a policy class can only model one policy
      concept.

   2. The early separation of policies.

        template<class Policies> class smart_ptr;
          vs
        template<class P0, class P1, class P2, class P4> class smart_ptr;

   3. The composition of state and behaviour in the policies.

-- 
Daniel Wallin

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