Wrapping C create and destroy functions using a smart pointer

The std::shared_ptr is fully capable to create and delete an object with cutstom creator and deleter, but instead of new you have to use the creator function.

Let's consider, we have the following creator and deleter:

typedef struct {
    int m_int;
    double m_double;
} Foo;

Foo* createObject(int i_val, double d_val) {
    Foo* output = (Foo*)malloc(sizeof(Foo));

    output->m_int = i_val;
    output->m_double = d_val;

    puts("Foo created.");
    return output;
}

void destroy(Foo* obj) {
    free(obj);
    puts("Foo destroyed.");        
}

To manage an instance of Foo created by functions above, simply do the following:

std::shared_ptr<Foo> foo(createObject(32, 3.14), destroy);

Using the std::shared_ptr is an overhead if you don't wish to share the object's ownership. In this case the std::unique_ptr is much better but for this type you have to define a custom deleter functor with which it can delete the managed Foo instance:

struct FooDeleter {
    void operator()(Foo* p) const {
        destroy(p);
    }
};
using FooWrapper = std::unique_ptr<Foo, FooDeleter>;

/* ... */

FooWrapper foo(createObject(32, 3.14));

C++17.

template<auto X> using constant_t=std::integral_constant<std::decay_t<decltype(X)>, X>
template<auto X> constexpr constant_t<X> constant{};
template<class T, auto dtor> using smart_unique_ptr=std::unique_ptr< T, constant_t<dtor> >;

Now suppose you have a C API wrapping Bob with Bob* createBob(some_args...) and destroyBob(Bob*):

using unique_bob=smart_unique_ptr< Bob, destroyBob >;
unique_bob make_unique_bob(some_args args){
  return unique_bob( createBob(args) );
}

a unique_bob can be implicitly moved into a shared_ptr<Bob>.

A bit of an extra assumption can make this work in C++14:

template<class T, void(*dtor)(T*)> using smart_unique_ptr=std::unique_ptr< T, std::integral_constant<decltype(dtor),dtor> >;

which assumes the dtor signature is void(T*).

In C++11 you have to write a new stateless function pointer dispatcher for zero overhead unqiue ptrs.