Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Are there any proposals to extend static_pointer_cast to unique_ptr?

99 views
Skip to first unread message

Joe Gottman

unread,
Jun 4, 2007, 9:40:10 PM6/4/07
to

std::shared_ptr defines three useful functions for doing explicit
casts on shared_ptr's: static_pointer_cast, dynamic_pointer_cast, and
const_pointer_cast. Has anyone proposed extending these in the obvious
way to the new unique_ptr class? I think this would be very useful,
especially in template code and when combined with the new auto syntax.

Joe Gottman

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

Greg Herlihy

unread,
Jun 5, 2007, 2:46:07 AM6/5/07
to
On Jun 4, 6:40 pm, jgott...@carolina.rr.com (Joe Gottman) wrote:
> std::shared_ptr defines three useful functions for doing explicit
> casts on shared_ptr's: static_pointer_cast, dynamic_pointer_cast, and
> const_pointer_cast. Has anyone proposed extending these in the obvious
> way to the new unique_ptr class? I think this would be very useful,
> especially in template code and when combined with the new auto syntax.

In what sort of expression would you envision using a
static_pointer_cast with a unique_ptr? Unlike a shared_ptr, a
unique_ptr is not copyable - so it is difficult for me to see how
static_pointer_cast() could be implemented for a unique_ptr in such a
way that static_pointer_cast() could not be used to make a copy of the
unique_ptr.

Granted, a unique_ptr may be "moved" to (or swapped with) another
unique_ptr - but to support both of those operations requires only a
suitably declared swap() routine and a move constructor for unique_ptr
- and not a cast operation upon the unique_ptr template class itself.

Greg

Joe Gottman

unread,
Jun 5, 2007, 12:07:51 PM6/5/07
to
Greg Herlihy wrote:
> On Jun 4, 6:40 pm, jgott...@carolina.rr.com (Joe Gottman) wrote:
>> std::shared_ptr defines three useful functions for doing explicit
>> casts on shared_ptr's: static_pointer_cast, dynamic_pointer_cast, and
>> const_pointer_cast. Has anyone proposed extending these in the obvious
>> way to the new unique_ptr class? I think this would be very useful,
>> especially in template code and when combined with the new auto syntax.
>
> In what sort of expression would you envision using a
> static_pointer_cast with a unique_ptr? Unlike a shared_ptr, a
> unique_ptr is not copyable - so it is difficult for me to see how
> static_pointer_cast() could be implemented for a unique_ptr in such a
> way that static_pointer_cast() could not be used to make a copy of the
> unique_ptr.
>
> Granted, a unique_ptr may be "moved" to (or swapped with) another
> unique_ptr - but to support both of those operations requires only a
> suitably declared swap() routine and a move constructor for unique_ptr
> - and not a cast operation upon the unique_ptr template class itself.
>
> Greg

Suppose you have an object p of type unique_ptr<Base> and you know that
p.get() is of type Derived * (Base has a virtual destructor and Derived
inherits publicly from Base). In that case, it is reasonable to want to
move p to a unique_ptr<Derived>. Currently we can do this as
unique_ptr<Derived> p2(static_cast<Derived *>(p.release()));
but this is verbose and slightly error-prone. If you use p.get()
instead of p.release() the code still compiles but you later have a
double-delete and a crash. If we instead declare a pair of
static_pointer_cast functions:

// DON'T DEFINE THIS FUNCTION, JUST DECLARE IT
template <class Dest, class Source>
unique_ptr<Dest, Destructor>
static_pointer_cast<Dest>(unique_ptr<Source> &p);


template <class Dest, class Source>
inline unique_ptr<Dest, Destructor>
static_pointer_cast<Dest>(unique_ptr<Source> &&p)
{
return unique_ptr<Dest>(static_cast<Dest *>(p.release()));
}

then users can just write
unique_ptr<Derived> p2(move(p1));

and if they make the natural mistake of writing
unique_ptr<Derived> p2(p1);

the result will be a link-time error as they call the first, undefined
function. Link-time errors are much better than compile-time errors
because they cannot be overlooked and their causes are more obvious.
Note that if the "Defaulted and Deleted Functions" proposal
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2210.html) is
accepted then we can declare the first function as a deleted function
and thus cause a compile-time error, which is even better than a
link-time error for focusing attention directly on the source of the error.

Joe Gottman

0 new messages