Firstly, it's election day so get out there and vote! Secondly, I went to bed last night and dreamt about functors! Last Friday I code-reviewed some changes made by one of my colleagues and his code just happened to use some STL containers and all sorts of related goodies. The last time I tried to use STL was about eight years ago when I was still at college and, admittedly, I didn't use them much: compiler support (both on Unix and Windows platforms) was not great and so I ended up using Matlab for most of my work instead.
Anyway, this got me thinking: wouldn't it be nice to be able to use the STL auto_ptr template to manage Windows handles in addition to regular old object pointers? Unfortunately, this was a no-go for two main reasons:
So, I began to write my own. First, I thought I'd steal some inspiration from the auto_ptr and shared_ptr classes. Unfortunately, this is not easy as it might sound. Anybody who has ever read the source code for STL would likely agree with me on this: the STL headers are not designed to be humanly readable as far as I can tell. Therefore I had to write it from scratch and reproduced below is my scoped_handle implementation:
Click to view source code for scoped_handle
Of course, I went through several iterations before I got it right. The first used a single encapsulated deleter function pointer. This suffered from the main issue that the deleter function had to conform to a very specific function prototype. Thus it becomes difficult to produce a generic class that can handle void (*)(HANDLE) functions and BOOL (*)(HANDLE) equally well (CloseHandle belonging to the latter category). After some head scratching I developed the implementation listed above based on the STL-style concept of functors. Specifically, this template class can handle any object, be it a function or class or anything else, as long as it supplies an overload of operator() that takes a single appropriately typed argument. This operator can return any type since scoped_handler ignores the return value anyway.
A few caveats become obvious:
This is roughly how one might use the scoped_handle class in conjunction with common Windows APIs:
Click to view source code for example of usage
See you next time!