This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [c++0x] unique_ptr.hpp implementation


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]