How do I use a custom deleter with a std::unique_ptr member?

Assuming that create and destroy are free functions (which seems to be the case from the OP's code snippet) with the following signatures:

Bar* create();
void destroy(Bar*);

You can write your class Foo like this

class Foo {

    std::unique_ptr<Bar, void(*)(Bar*)> ptr_;

    // ...

public:

    Foo() : ptr_(create(), destroy) { /* ... */ }

    // ...
};

Notice that you don't need to write any lambda or custom deleter here because destroy is already a deleter.


It's possible to do this cleanly using a lambda in C++11 (tested in G++ 4.8.2).

Given this reusable typedef:

template<typename T>
using deleted_unique_ptr = std::unique_ptr<T,std::function<void(T*)>>;

You can write:

deleted_unique_ptr<Foo> foo(new Foo(), [](Foo* f) { customdeleter(f); });

For example, with a FILE*:

deleted_unique_ptr<FILE> file(
    fopen("file.txt", "r"),
    [](FILE* f) { fclose(f); });

With this you get the benefits of exception-safe cleanup using RAII, without needing try/catch noise.


You just need to create a deleter class:

struct BarDeleter {
  void operator()(Bar* b) { destroy(b); }
};

and provide it as the template argument of unique_ptr. You'll still have to initialize the unique_ptr in your constructors:

class Foo {
  public:
    Foo() : bar(create()), ... { ... }

  private:
    std::unique_ptr<Bar, BarDeleter> bar;
    ...
};

As far as I know, all the popular c++ libraries implement this correctly; since BarDeleter doesn't actually have any state, it does not need to occupy any space in the unique_ptr.