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:36:35


On Tue, Mar 21, 2017 at 2:22 PM, Richard Hodges via Boost <
boost_at_[hidden]> wrote:

> Here's a first cut of a polymorphic deleter (which at least allows you to
> spell the name of the unique_ptr<A> in the example). It's not optimally
> efficient, but a little SFO should do it.
>
> #include <memory>
> #include <iostream>
>
> namespace notstd {
>
> class polymorphic_deleter
> {
> struct concept
> {
> virtual void impl_call() const = 0;
> };
>
> template<class T, class Deleter>
> struct model final
> : concept
> {
> model(T *p, Deleter del)
> : p_(p)
> , del_(std::move(del)) {}
>
> void impl_call() const
> {
> del_(p_);
> }
>
> T *p_;
> Deleter del_;
> };
>
> std::unique_ptr<concept> impl_;
>
> template<class T, class Del>
> static auto make_model(T* p, Del&& del)
> {
> using deleter_type = std::decay_t<Del>;
> using pointer_type = T;
> return std::make_unique<model<pointer_type, deleter_type>>
> ( p, std::forward<Del>(del) );
> };
>
> public:
>
> template<class T, class Del>
> polymorphic_deleter(T* p, Del&& del)
> : impl_(make_model(p, std::forward<Del>(del)))
> {}
>
> void operator()(void*) const {
> impl_->impl_call();
> }
>
> };
>
> template<class T, class...Args>
> auto make_polymorphic_unique(Args&&...args)
> {
> auto pt = std::make_unique<T>(std::forward<Args>(args)...);
> auto del = polymorphic_deleter(pt.get(), std::default_delete<T>());
> return std::unique_ptr<T, polymorphic_deleter>(pt.release(),
> std::move(del));
> };
>
> }
>
> struct A
> {
> ~A() { std::cout << "deleting A\n"; }
> };
>
> struct B : A
> {
> ~B() { std::cout << "deleting B\n"; }
> };
>
> int main()
> {
> auto pb = notstd::make_polymorphic_unique<B>();
> auto pa = std::unique_ptr<A, notstd::polymorphic_deleter>(
> std::move(pb));
> pa.reset();
> }
>

Class `polymorphic_deleter` is implementation of the `function<void (void
*)>` without small object optimization. Yes, it is possible to use
unique_ptr with such deleter, but it requires additional memory allocation
even for the case when deleter is std::default_delete. I have tried to
avoid this.

-- 
Andrey Davydov

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