|
Boost : |
From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2002-04-19 12:14:49
"Fernando Cacciola" <fcacciola_at_[hidden]> wrote in message
news:a9pfv7$cb7$1_at_main.gmane.org...
> Just my 2 cents...
>
> Scenario 1: I want to write a class which does something with a given
> source object. This class needs to keep the object alive, but it is quite
> possible that the caller disposes the object even before this class
> completes its task. This scenario calls for a common pattern:
>
> class Processor
> {
> Processor ( smart_ptr<A> const& obj ) : m_obj(obj) {}
> ...
> smart_ptr<A> m_obj ;
> } ;
>
>
> The important thing in this example is that all I really know of is A, and
> that I need it to be alive as long as Proccesor needs it.
> If smart_ptr<> is intrusively-policy-based, I -the user of A- must make
> decisions about which of those policies would fit here. Some of those
> decisions might be hard to take on this side of the system, but even if
can
> take them, there is still this problem:
> Suppose I do:
>
> Processor ( smart_ptr<A,Policy1,Policy2> const& obj ) : m_obj(obj) {}
>
> what happens with the caller?
>
> Likely, there is a smart_ptr<> holding A objects on the caller side
already.
> If the caller has a different (in terms of policies) smart_ptr, he could
> probably -given the appropriate machinery- do a conversion, but this is
> unlikely to scale well, so, most likely, Processor will eventually end up
> being parametrized:
>
> template<class APtr>
> class Processor
> {
> Processor ( APtr const& obj ) : m_obj(obj) {}
> ...
> APtr m_obj ;
> } ;
>
> These, however, intoduces a much higher engineering complexity to the
> system, because we have changed a non-template class to a template class
> only because the smart_ptr is overparametrized (from the pov of the user
of
> A who just wants to keep it alive).
No. I disagree. Real problem here you want to reuse you Processor facility,
but do not know storage type. There as usual two choises runtime
polimorphizm - which I hardly believe you can accept, or compile-time one
with we usually express in form of template parameters. And FWIW it does not
"intoduces a much higher engineering complexity".
>
> Scenario 2:
>
> It is quite common to specialize certain things -such as predicates- on a
> smart_ptr<>. This is in order to allow certain expressions to be applied
> indistinctely to bare and smart pointers.
> For example, the boost shared-ptr declares:
>
> // get_pointer() enables boost::mem_fn to recognize shared_ptr
> template<typename T> inline T * get_pointer(shared_ptr<T> const & p) ;
>
> This is used -as the comment says- inside mem_fn which allows a very
> powerful usage of mem_fn.
>
> If shared_ptr were intrusively policy-based, this wouldn't be feasible
> becuase mem_fn couldn't know about the smart pointer policies.
Why? Can't you write another predicate like this:
template<typename StoragePolicy,...> inline StoragePolicy::pointer_type
get_pointer(smart_ptr<....> const & p) ;
>
>
> So....
>
> Just as is the case with optional<>, a smart pointer is a library fature
so
> general that the ability to express a smart pointer as a single-parameter
> template class: smart_ptr<T> is so powerful that directly competes with
the
> power of the flexibility given by a policy-based class.
>
>
> Intrusive vs external policies:
>
> Since the real problem is not the usage of policies as compile-time
> strategic-drivers for the smart ptr, but instrumenting the approach using
> intrusive policies, it appears to me that the obvious solution is to use
> external policies, as optional<> does.
>
> An external policy is just like any other policy template class, except
that
> is is identified by a fixed template-id.
> A good example of it is std::iterator_traits<>. This is an external policy
> class, with a fixed template-id, so you don't need to pass it as an
> argument.
The thing is that for given iterator type most probably you using always.
the same iterator_traits, while this is not the case for smart_ptr policies
(with rare exclusions)
>
> Of course, external policies are a lot less flexible than their intrusive
> counterparts.
>
The whole point of policy-based design is it's flexibility.
> Dietmar already shown -and I totally agree- that most of the smart ptr
> policies are usually type dependent, so they perfectly call for external
> policies. (BTW, the sketch made by Doug seems very reasonable).
I disagree here. What is type dependent? Specifically?
> --
> Fernando Cacciola
> Sierra s.r.l.
> fcacciola_at_[hidden]
> www.gosierra.com
>
Gennadiy.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk