I am attempting to use std::unique_ptrs to manage Windows HANDLEs in an exception-safe manner.
First I tried:
struct HandleDeleter
{
void operator()( HANDLE handle )
{
if( handle )
{
FindVolumeClose( handle )
}
}
}
typedef std::unique_ptr< HANDLE, HandleDeleter > unique_vol_handle_t;
Later in my code when I try to use it:
unique_vol_handle_t volH( FindFirstVolumeW( buffer, MAX_GUID_PATH ) );
I get the following error from Visual Studio 2012RC:
1> error C2664: 'std::unique_ptr<_Ty,_Dx>::unique_ptr(std::nullptr_t) throw()' : cannot convert parameter 1 from 'HANDLE' to 'std::nullptr_t'
1> with
1> [
1> _Ty=HANDLE,
1> _Dx=VolumeHandleDeleter
1> ]
1> nullptr can only be converted to pointer or handle types
referencing the volH declaration line, immediately above.
After searching for some time, I found a blog article which basically says, add:
typedef HANDLE pointer;
to the top of the struct declaration, and all will be well.
I didn't believe it, but I tried it and it did resolve the error. I'm puzzled how defining a type (without even referencing it) could make such a difference.
Two questions:
1) Can you explain the original error? I don't understand why the compiler is referring to std::nullptr_t/nullptr
.
2) How is it that the typedef resolves this (or at least appears to)? Is there a less 'spooky action at a distance' solution to this?