
On Tue, Mar 21, 2017 at 2:15 PM, Andrey Semashev via Boost < boost@lists.boost.org> wrote:
On 03/21/17 12:54, Andrey Davydov via Boost wrote:
On Tue, Mar 21, 2017 at 12:00 PM, Richard Hodges
wrote: What is required, more than simply creating a type-erased deleter?
Also deleter must capture pointer, because pointer which was passed to constructor can differ from the pointer which will be deleted. For example,
struct Base { /* ... */ }; struct Derived : Base { /* ... */ };
ptr<Derived> p1(new Derived); void * raw_p1 = p1.get(); ptr<Base> p2 = std::move(p1); void * raw_p2 = p2.get(); assert(raw_p1 != raw_p2);
The above piece of code strikes me as very unsafe and better be avoided in the first place. Designing new tools to handle this case is IMHO misguided.
Why this code is very unsafe? If change `ptr` to `shared_ptr` this will become perfectly valid and widely used pattern.
Now, I can understand the need to perform casts on smart-pointers, but they should still provide some level of safety, at least the same level that is provided by pointer casts in the core language. But supporting casts should not require a new smart-pointer. And indeed it doesn't:
template< typename U, typename T, typename D > std::unique_ptr< U, D > static_pointer_cast( std::unique_ptr< T, D >&& p) { D d = p.get_deleter(); return std::unique_ptr< U, D >( static_cast< U* >(p.release()), std::move(d)); }
What is `D`? If it is std::default_delete<T> then function result type will be std::unique_ptr and unlikely this type is very useful (even if it compiles).
The other part of your proposal, which is polymorphic behavior with a deleter knowing the type to call the destructor on, can be solved by a custom deleter. I'm not sure a generalized version of such deleter would have a large demand, given that there is the alternative TONGARI J suggested, but I'm not opposed to a proposal.
May be I doesn't understand what TONGARI J suggested, but how can
`unique_ptr