#include <iostream>
using namespace std;
//-----
typedef void* HANDLE;
#define INVALID_HANDLE_VALUE ((HANDLE)(-1))
HANDLE CreateFile(...) { return INVALID_HANDLE_VALUE; }
HANDLE CreateFileMapping(HANDLE, ...) { return NULL; }
void CloseHandle(HANDLE h) { std::cout << "closed: " << h << std::endl; }
//-----
struct InvalidHandleTraits
{
using HandleType = HANDLE;
static constexpr HANDLE DefaultHandle = INVALID_HANDLE_VALUE;
//...
static void Close(HANDLE h) { CloseHandle(h); }
//...
};
struct NullHandleTraits
{
using HandleType = HANDLE;
static constexpr HANDLE DefaultHandle = NULL;
//...
static void Close(HANDLE h) { CloseHandle(h); }
//...
};
template<typename traits = InvalidHandleTraits>
class HandleWrapper
{
public:
using HandleType = typename traits::HandleType;
HandleWrapper(HandleType h = traits::DefaultHandle) : m_handle(h) { std::cout << "constructor: " << h << std::endl; }
~HandleWrapper() { traits::Close(m_handle); }
//...
operator HandleType() { return m_handle; }
private:
HandleType m_handle;
};
int main()
{
HandleWrapper<> h1 = CreateFile();
HandleWrapper<NullHandleTraits> h2 = CreateFileMapping(h1);
return 0;
}