C++'s destructors are great for ensuring that resources get cleaned up at the end of a scope, but writing wrapper classes for every damn C library type you use gets tired real quick. Slava suggested that I write a template class to do it once, so guess what? I did.
template<typename T>
struct finally {
typedef T value_type;
typedef boost::function<void (T)> destructor_type;
T object;
destructor_type destructor;
finally(T o, destructor_type d) : object(o), destructor(d) {}
~finally() { destructor(object); }
};
With finally in your toolbox, whenever you need to toss a fopen, malloc, or other C resource acquisition in, you don't need to give up exception safety anymore!
{
FILE *f = fopen("foo", "r");
finally<FILE*> close_f(f, fclose);
}
{
void *buf = malloc(17);
finally<void*> free_buf(buf, free);
}
{
PGconn *conn = PQconnectdb(conninfo);
finally<PGconn*> finish_conn(conn, PQfinish);
}
Because finally uses boost::function to hold the destructor function, it works with functor objects and functions that don't return void.
UPDATE: kefex on reddit points out that boost::shared_ptr does this already:
boost::shared_ptr<FILE> pf(fopen("foo", "r"), fclose);