Using std::unique_ptr for Windows HANDLEs

The implementation of unique_ptr checks for the presence of a ::pointer type on the deleter. If the deleter has a ::pointer type then this type is used as the pointer typedef on the unique_ptr. Otherwise a pointer to the first template argument is used.

According to cppreference.com, the unique_ptr::pointer type is defined as

std::remove_reference<D>::type::pointer if that type exists, otherwise T*


From the MSDN manual on unique_ptr:

The stored pointer to an owned resource, stored_ptr has type pointer. It is Del::pointer if defined, and Type * if not. The stored deleter object stored_deleter occupies no space in the object if the deleter is stateless. Note that Del can be a reference type.

This means that if you provide a deleter functor it have to provide a pointer type that is used for the actual pointer type of the unique_ptr. Otherwise it will be the a pointer to your provided type, in your case HANDLE* which isn't correct.


I've been doing the following for various types of handles in Windows. Assuming we have declared somewhere:

std::unique_ptr<void, decltype (&FindVolumeClose)> fv (nullptr, FindVolumeClose);

This is populated with:

HANDLE temp = FindFirstVolume (...);
if (temp != INVALID_HANDLE_VALUE)
    fv.reset (temp);

No need to declare a separate struct to wrap the deleters. Since HANDLE is really a void * the unique_ptr takes void as its type; for other kinds of handles, that use the DECLARE_HANDLE macro, this can be avoided:

// Manages the life of a HHOOK
std::unique_ptr<HHOOK__, decltype (&UnhookWindowsHookEx)> hook (nullptr, UnhookWindowsHookEx);

And so on.