Search code examples
c++shared-ptr

How to use a shared_ptr for the deleter only?


I simply want to use the deleter feature of a shared_ptr without using the shared_ptr part. As in, I want to call a function when the shared_ptr goes out of scope and the deleter doesn't need any pointer passed to it.

I have this but it's cheezy.

shared_ptr<int> x(new int, [&](int *me) { delete me; CloseResource(); }); 

Is there a way to not associate any pointer with the shared_ptr?

Update: as per many suggestions, the unique_ptr way would look like this:

unique_ptr<int, std::function<void(int*)>> x(new int, [&](int *me) {delete me; CloseResource();});

Which frankly looks worse than the shared_ptr version, as much 'better' as it is.

Update: for those who like using this simple scope closing function caller I made it a bit simpler, you don't even need to allocate or free an object:

shared_ptr<int> x(NULL, [&](int *) { CloseResource(); });

Solution

  • It sounds like what you may be trying to do is turn over "delete" responsibilities to "somebody else" so you no longer have to worry about it. If that's the case, unique_ptr (not shared_ptr) with a custom deleter will work:

    struct Foo final {};
    Foo* New() { return new Foo; }
    void Delete(Foo* p) { delete p; }
    
    int main()
    {
        auto p = New();
        std::unique_ptr<Foo, decltype(&Delete)> up(p, &Delete);
    }
    

    There are a number of similar solutions listed here; there's not much more that can be done without more information about your actual API (e.g., does the HANDLE is really a pointer trick work?). And even more reading at The simplest and neatest c++11 ScopeGuard, including a link to a proposed std::unique_resource.