From: Peter Dimov (pdimov_at_[hidden])
Date: 2002-04-03 13:30:53
From: "Raoul Gough" <RaoulGough_at_[hidden]>
> > From: "Peter Dimov" <pdimov_at_[hidden]>
> > Right again. However, the primary methods of accessing a weak_ptr are
> > constructing a shared_ptr (which does throw) and (2) make_shared. get()
> > been retained for efficiency but is not recommended (in multithreaded
> > programs.)
> So why the difference in error semantics between the single and
> multi-threaded idioms? For example, if I converted single-threaded code
> uses get() to thread-safe code using make_shared, I also get changed
> semantics for the invalid pointer case.
Changed semantics? Why? Both get() and make_shared() return a NULL pointer.
> Incidentally, it looks like the use_count member function can determine
> indirectly whether the target still exists or not. It seems a bit obscure
> though, seeing as the reference count is really an implementation detail
> distinct from the concept of null/valid/invalid.
Correct, that's why I added weak_ptr::expired().
> BTW, am I right in thinking that sharede_ptr always maintains an extra
> reference counter? I mean, even if my code doesn't use weak_ptr,
> still has to maintain the extra counter, right? That, combined with the
> thread-safety features seems to cost something like a 10% performance hit
> my smart pointer benchmark code (which sorts indexes to objects containing
> two strings each). That's on the total sorting time, not pointer access
Yes, you are right. It does make a difference in benchmarks.
> It seems like boost is deliberately trying to avoid extra template
> parameters for things like policies or allocators. OTOH, it seems a bit
> unfair for code to pay for features which it doesn't require (e.g. thread
> safety or weak_ptr support). Has the option of adding an additional policy
> parameter to the shared_ptr template already been discussed?
Numerous times. Usually people don't agree on the meaning of the additional
policy parameter. :-)
Keeping shared_ptr non-parameterized has an important benefit: its type
doesn't change. I can define my library interface in terms of shared_ptr<T>
and it will happily interoperate with every other shared_ptr<>-using
library. Once you add that policy parameter, library A that chooses policy X
will no longer talk to library B that chooses policy Y, and using both
libraries becomes problematic.
This doesn't mean, of course, that we don't need a parameterized smart
pointer. Only that (a) shared_ptr is not it, and (b) shared_ptr plus an
additional policy parameter is not it.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk