Topic: Inconsistencies in unique_ptr and shared_ptr APIs


Author: SG <s.gesemann@gmail.com>
Date: Mon, 8 Jun 2009 13:20:44 CST
Raw View
On 8 Jun., 04:16, Scott Meyers <use...@aristeia.com> wrote:
> In September 2005, Joe Gottman posted to this group about
> inconsistencies in the interfaces for unique_ptr and shared_ptr that
> bore no apparent relationship to their fundamental functionality
> (http://tinyurl.com/nmjwuu). He noted that:
> - "Shared_ptr has only operator ==, operator !=, and operator <.
>   Unique_ptr has these three plus operator >, operator <=, and
>   operator>=."
> - Only unique_ptr has special support for arrays.
> - Only shared_ptr supports const_pointer_cast, static_pointer_cast,
>   and dynamic_ptr_cast.
>
> These discrepancies are also present in the current C++0x draft
> (N2857), so presumably there is a reason for them.  Can somebody
> please explain what is is?

I have to agree I find this a little odd.

> I'd also be interested to know why the type of the deleter is part
> of the type of a unique_ptr but is not part of the type of a
> shared_ptr.

I asked myself the same question. In addition to Daniel's points I'd
like to make the following: A unique_ptr type that is "deleter-
agnostic" requires some kind of dynamic memory allocation and
polymorphism. For shared_ptr this is not a big issue since a reference
counter needs to be allocated anyways and both, reference counter and
deleter, can be combined into a single object. But for unique_ptr
forcing this kind of polymorhism onto it doesn't seem like a good
idea. Instead it should be optional (for example via std::function<void
(T*)> as the deleter's type).

Cheers!
SG


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <usenet@aristeia.com>
Date: Sun, 7 Jun 2009 20:16:49 CST
Raw View
In September 2005, Joe Gottman posted to this group about inconsistencies in the
interfaces for unique_ptr and shared_ptr that bore no apparent relationship to
their fundamental functionality ( http://tinyurl.com/nmjwuu ). He noted that:
- "Shared_ptr has only operator ==, operator !=, and operator <.  Unique_ptr has
these three plus operator >, operator <=, and operator>=."
- Only unique_ptr has special support for arrays.
- Only shared_ptr supports const_pointer_cast, static_pointer_cast, and
dynamic_ptr_cast.

These discrepancies are also present in the current C++0x draft (N2857), so
presumably there is a reason for them.  Can somebody please explain what is is?

I'd also be interested to know why the type of the deleter is part of the type
of a unique_ptr but is not part of the type of a shared_ptr.

Finally, I'd like to know why unique_ptr gets its own subsection in the standard
(20.8.12) rather than being under "Smart pointers" (20.8.13) with shared_ptr and
weak_ptr.  (Heck, weak_ptr isn't even really a pointer, because it doesn't
overload operator->.)

Thanks for all enlightenment.

Scott

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Mon, 8 Jun 2009 09:36:52 CST
Raw View
On Jun 8, 4:16 am, Scott Meyers <use...@aristeia.com> wrote:
> In September 2005, Joe Gottman posted to this group about inconsistencies in the
> interfaces for unique_ptr and shared_ptr that bore no apparent relationship to
> their fundamental functionality (http://tinyurl.com/nmjwuu). He noted that:
> - "Shared_ptr has only operator ==, operator !=, and operator <.  Unique_ptr has
> these three plus operator >, operator <=, and operator>=."
> - Only unique_ptr has special support for arrays.
> - Only shared_ptr supports const_pointer_cast, static_pointer_cast, and
> dynamic_ptr_cast.
>
> These discrepancies are also present in the current C++0x draft (N2857), so
> presumably there is a reason for them.  Can somebody please explain what is is?

Concerning the comparison operators I think that they are present,
even
though they are not individually specified in terms of effects. Note
that according
to [memory]/2 header <memory> synopsis *all* comparison operators are
listed, just search for the block

"// 20.8.13.2.7, shared_ptr comparisons:"

Now it's true that [util.smartptr.shared.cmp] doesn't list the
remaining four,
but this is not really necessary, because [operators] does explicitly
say so

"In this library, whenever a declaration is provided for an operator!
=, operator>,
operator>=, or operator<=, and requirements and semantics are not
explicitly
provided, the requirements and semantics are as specified in this
clause."

Joe Gottman's original posting was probably true, because the
remaining
comparison operator where added afterwards after applying the
proposal:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2637.pdf

during the Sophia Antipolis meeting 2008.

I have no special position whether shared_ptr should support array
pointers and I'm not aware of the reasons why it currently does not
support them explicitly. The suggested additions of moving casts
for unique_ptr look interesting.

> I'd also be interested to know why the type of the deleter is part of the type
> of a unique_ptr but is not part of the type of a shared_ptr.

Both smart pointer types have different use cases. Unique_ptr is the
de facto
replacement for auto_ptr, but it added the deleter facility to support
more
general deletion concepts. This should be done to allow the least
necessary
memory overhead which has the slight disadvantage that the deleter
influences the type of unique_ptr. This disadvantage can be worked-
around with
by using a deleter delegating to function pointers or polymorphic
functors.

Shared_ptr is intentionally designed to be *only* dependent on the
stored
pointer of some given type, so the deleter is not part of the smart
pointer
type. Their are much less advantages to put the deleter into the
type,
because this pointer type is restricted to native pointers. This is
not so for
unique_ptr, which basically supports any pointer-like type, because it
considers whether it's deleter provides a corresponding typedef.
It is probably true, that shared_ptr could be extended like that, but
no convincing arguments had been provided yet to do so.

> Finally, I'd like to know why unique_ptr gets its own subsection in the standard
> (20.8.12) rather than being under "Smart pointers" (20.8.13) with shared_ptr and
> weak_ptr.

This is a pure editorial decision and it may happen that will be
restructured.

Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]