Boost logo

Boost :

Subject: Re: [boost] [smart_ptr] Is there any interest in unique_ptr with type erased deleter?
From: Andrey Davydov (andrey.a.davydov_at_[hidden])
Date: 2017-03-21 11:54:10


On Tue, Mar 21, 2017 at 2:15 PM, Andrey Semashev via Boost <
boost_at_[hidden]> wrote:

> On 03/21/17 12:54, Andrey Davydov via Boost wrote:
>
>> On Tue, Mar 21, 2017 at 12:00 PM, Richard Hodges <hodges.r_at_[hidden]>
>> 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<U, std::default_delete<T>> 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<T,
void(*)(T*)>` hold stateful deleter?

-- 
Andrey Davydov

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk