This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [c++0x] unique_ptr.hpp implementation
- From: "Jonathan Wakely" <jwakely dot gcc at gmail dot com>
- To: "Chris Fairles" <chris dot fairles at gmail dot com>
- Cc: libstdc++ at gcc dot gnu dot org
- Date: Sun, 12 Aug 2007 22:52:03 +0100
- Subject: Re: [c++0x] unique_ptr.hpp implementation
- References: <fac6bb500708121236t7231f2c2s5d4afec494e5b728@mail.gmail.com>
On 12/08/07, Chris Fairles <chris.fairles@gmail.com> wrote:
> Attached is an implementation of unique_ptr (according to
> N2315=07-0175) along with a test suite (albiet, incomplete). This
> implementation is largely based on:
> http://home.twcny.rr.com/hinnant/cpp_extensions/unique_ptr.html
>
> Noteable differences are:
> - uses c++0x type traits (enable_if, conditional etc)
> - EBO without the use of boost's compreessed_ptr
> - disable reset in array specializations for convertible pointer types
> - use pointer-to-private-member for unspecified bool/pointer types
Hi Chris, thanks for sharing your code with GCC, I'm really looking
forward to the day when I can use a GCC that supports all of C++0x.
I haven't given this a thorough review yet, but I noticed a couple of
problems that should be easy to fix. Details below.
> Issues:
> - should you be able to use function pointers as a deleter? i.e.
> void d(int *p){delete p;}
> int* p = new int;
> unique_ptr<int, void(*)(int*)> ptr(p, &d);
Yes, I believe that should work.
> - can't use member function ptrs in a similar manner since you have to
> use .* or ->* to call member function and that requires an object
> which you don't have
std::bind() will be used to get around this.
> I'd appreciate some feedback, like how well it fits the standard since
> this is my first attempt at implementing straight out of a c++ std.
> Any design issues or subtle flaws as well.
I believe the following should compile, but doesn't with your
implementation, due to the extra DeleterIsEmpty template parameter:
template <template <class, class> class>
void f()
{
}
int main()
{
f<std::unique_ptr>();
}
Secondly, inheriting from the empty deleter is not advisable, since
the deleter type could define virtual function with arbitrary names,
which would change the meaning of the unique_ptr, possibly even
failing to compile. For example:
struct X {
virtual void get() const { }
void operator()(int* p) { delete p; }
};
std::unique_ptr<int, X> p(new int);
This won't compile, because the return type of unique_ptr::get is
different to that of X::get.
Both these problems can be avoided by getting rid of the
specialisation using enable_if. See how the EBO is used in the
libstdc++ container types for a safe alternative e.g. _Vector_impl in
bits/stl_vector.h.
Regards,
Jon