Boost logo

Boost :

From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2002-04-19 12:14:49

"Fernando Cacciola" <fcacciola_at_[hidden]> wrote in message
> 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
> 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
> 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
> 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
> 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
> 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
> 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]


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