|
Boost : |
From: DKl_at_[hidden]
Date: 2002-04-19 15:07:21
Andrei Alexandrescu wrote:
<DKl_at_[hidden]> wrote:
> > I can agree with this although only with the following restriction:
> > It has to be complemented by a smart pointer template with just one
> > template parameter, namely the type: This would be the type used in
> > interfaces. It should be configurable to use different policies for
> > different type but there is only one set of policies for a specific
> > type.
> But that's not "complementing". It is a template typedef. One certainly
> doesn't want to write the same code multiple times.
The typedef is a different entity than the policy-based smart pointer
although a specific typedef may effectively refer to a configuration
of a policy-based smart pointer. On the other hand, there is no
requirement that it always refers to a configuration of a policy-based
smart pointer. Taken together, I think this is what makes the issue
complementary.
> > Merely advising people to add appropriate typedefs is not sufficient
> > because there would have to be general agreement on the names of the
> > typedefs and their configuration.
> That is not "advice", it is project-wide policy and is established by
> the architect(s).
My experience with imposing policies on third parties is that it does
not work, not even if there are really bright and/or mean architects.
Of course, even if we have 'boost::shared_ptr<T>' or even
'std::shared_ptr<T>' nobody guarantees that third parties use just this
class in their interfaces. However, chances that they do are
considerably bigger than that they happen to use the same selection of
policies used in the other third part project for some policy-based
smart pointer.
> > Of course, this issue is quite orthogonal to policy-based smart
> > pointers but my impression of the recent discussion on smart pointers
> > was that the intended change is replacing 'boost::shared_ptr' by a
> > policy-based smart pointer.
> I believe the two will coexist at least until template typedefs make it
> into the mainstream, at least on backward compatibility grounds.
My point is that they not only will coexist but that they actually *have*
to coexists: one without the other makes no sense! For interfaces
having only a policy-based smart pointer is evil. For individual types
having only one choice (ie. the current 'boost::shared_ptr') is also
evil (however, since everybody seemed to be keen on replacing the latter
with the form I didn't state that 'boost::shared_ptr<T>' is evil: that
would have been oil on the flames...). They are both only viable
together!
Taken together, ie. having 'boost::shared_ptr<T>' being the choice used
by interfaces, implemented [at least typically] via a policy-based smart
pointer this forms the Dream Team.
> By the way, sometimes it is better to use a non-template type in
> interfaces.
Yes. However, if I need to an entity which is likely to be shared and
it happens to be passed around something like a smart pointer seems to
be the right idea. Even if you implement my own, special class for this
it does not help: This class would actually be off even worse because
it is guaranteed that it won't interoperate with other components!
A smart pointer (or smart handle, smart resource, whatever you call it)
is the right approach, even to interfaces. However, everybody using it
in an interface has to use the same approach because, the same
combination of policies to have things interact smoothly. THIS is what
'boost::shared_ptr<T>' (or however this beast is effectively called) is
good for. Effectively, it may be a typedef for a combination of policies
passed to a policy-based smart pointer (or, for the time until template
typedef are available, a suitable emulation of this). However, the mere
existence of the name together with an overridable default provides a
benefit to people designing interfaces (and, of course, their later
users).
Maybe my subject was too harsh: I'm *NOT* objecting to having and using
policy-based smart pointer. What I'm objecting to is having *only* these!
What is needed is also a name for type specific default configuration.
Of course, this configuration will not be suitable everywhere but just
as a default for interfaces if these have no specific needs it is a good
choice (in fact, even 'boost::shared_ptr<T>' in its current state is a
good choice): For specific needs, a different configuration of policies
can still be used. However, even without templatizing interfaces the
default will be a good choice to be used in an interface: without this
default some more or less arbitrary combination of policies would be
used which may or may not fit the arbitrary combination choosen for
another component.
... and from the way this discussion goes, it shows that this tought
was indeed missing! It is actually a pretty simple idea but it's effects
on interoperation between interfaces is actually quite tremendous. For
example, I think that a major part of COM's success was due to setting
up rules how objects are passed between components. Even though these
rules are not optimal for all situations, they are good enough in most.
-- <mailto:dietmar_kuehl_at_[hidden]> <http://www.dietmar-kuehl.de/> Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk