Search code examples
c++winapistlsmart-pointers

How to use a custom deleter using WinAPI with std::make_unique?


So I'm just experimenting with smart pointers and how I can manage Win32 HANDLE objects with them, so I wanted to test out this simple code I wrote.

It's supposed to provide a custom deleter for std::unique_ptr to use when the smart pointer goes outta scope.

template <typename Function>
class PtrDeleter
{
    Function _Closer;
public:
    void operator()(void* memBlock) const
    {
        _Closer(memBlock);
    }
};

//The std::make_unique is the one causing the problem...
std::unique_ptr<void*, PtrDeleter<decltype(CloseHandle)>> ptr = std::make_unique<void*>(OpenThread(...));

The reason I'm using a template for the Function parameter is because I'll be using other functions with CloseHandle, like CoTaskMemFree.

cannot convert from std::unique_ptr<void *,std::default_delete<_Ty>>' to 'std::unique_ptr<void *,PtrDeleter<BOOL (HANDLE)>>

This is what the compiler is outputting. Why is it still trying to use std::default_delete with std::make_unique?


Solution

  • make_unique returns unique_ptr with defaulted deleter.

    To provide your custom version you have to call unique_ptr(Pointer,Deleter) version of unique_ptr ctor:

    template <typename Function>
    class PtrDeleter {
        Function _Closer;
    public:
        void operator()(void* memBlock) const {
            _Closer(memBlock);
        }
    };
    
    int main() {
        PtrDeleter<decltype(&CloseHandle)> deleter;
        void* openThread = OpenThread(0,false,0);
        std::unique_ptr<void, decltype(deleter)> ptr(openThread,deleter);
    }
    

    Demo