El 02/09/2014 19:22, Peter Dimov escribió:
Ion Gaztañaga wrote:
On the other hand, with the default_deleter it could be safe to convert (maybe if N >= M):
4) unique_ptr
-> unique_ptr I don't support this conversion in shared_ptr and have no plans to. reinterpret_pointer_cast should work though.
Ok, I prototyped it and it worked, but found it too forced. You can always release(), cast and build a new unique_ptr if you are really sure what you are doing.
In general, if deleter<X> is convertible to deleter<Y> but does not handle Y properly, it might cause problems. So I'm not sure that this case is extraordinary in this sense.
I agree. If you declare deleter<X> is convertible to deleter<Y>, you declare it can delete objects of type Y after conversion.
It's true that these cases are a bit convoluted because, esp. in the presence of a user-defined pointer type, we need to decide how much to trust the deleter and how much to override whatever it says WRT conversions. For instance, let's say unique_ptr
wants to convert to unique_ptr and D1::pointer is convertible to D2::pointer and D1 is convertible to D2 _but_ X2 does not have a virtual destructor. Do we disallow the conversion as we do in the ordinary X1* -> X2* case when using the default deleter, or do we go ahead? The array case is similar, unique_ptr -> unique_ptr , X(*)[] is not convertible to Y(*)[] but both D1::pointer and D1 are convertible to D2::pointer and D2. Legal or not?
Semantics might be a bit more clear for default_delete, as it calls delete. std::is_polymorphic might not be very accurate, maybe std::has_virtual_destructor. A user-defined deleter could be a no-op or an operation that can properly recycle (link it in a intrusive list, etc.) the object even if it has no virtual destructor, just because it doesn't call the destructor. I think the implementation is nearly finished (has_virtual_destructor check is missing, as the standard does not require it, but it could be added). I've split tests and put all the meta utilities used by unique_ptr in a different header. Let me know if you feel some additional work must be done to push it into the "::boost" namespace and/or move it into smart_ptr. One missing decision is whether Boost.Move should be used in tests and/or use std::move/forward in C++11 compilers. And in case both approaches are testes in C++11 compilers, how we avoid duplicating test code. Ion