defer
allows the program to automatically release a source on demand. It is a
Go keyword, but can be implemented in C++ with std::unique_ptr
:
#include <functional>
template<typename T> using deleted_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
And use it like
{
deleted_unique_ptr<T> dptr(
raw_ptr,
[](auto p) { delete_func(p); }
);
}
The C++ world prefer to call this RAII scope guard, the resource release function
is called automatically when the std::unique_ptr
object is deconstructed, i.e.
on leaving the scope.
However, you can take one more step and make it imperative just like in Go.
#include <functional>
#define CONCAT(a, b) a ## b
#define __defer_impl(ptr, dfn, l) \
std::unique_ptr<std::remove_pointer<decltype(ptr)>::type, \
std::function<void(decltype(ptr))>> \
CONCAT(__dtor, l) (ptr, [](decltype(ptr) p) { dfn(p); })
#define defer(ptr, dfn) __defer_impl(ptr, dfn, __COUNTER__) // __LINE__ works as well
The
CONCAT()
macro is there to make sure__COUNTER__
expands, otherwise concatenate operator##
will suppress it.
Also, a
std::experimental::unique_resource
is around the corner.