Topic: Are there any proposals to extend static_pointer_cast to unique_ptr?
Author: jgottman@carolina.rr.com (Joe Gottman)
Date: Tue, 5 Jun 2007 01:40:10 GMT Raw View
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-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Greg Herlihy <greghe@pacbell.net>
Date: Tue, 5 Jun 2007 00:46:07 CST Raw View
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
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Joe Gottman <jgottman@carolina.rr.com>
Date: Tue, 5 Jun 2007 10:07:51 CST Raw View
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
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]