While exploring RAII, I found this post scope(exit) in C++ 11 that talks about a technique also called scope guard. The concept of “scope guard” was proposed by Andrei Alexandrescu and Petru Marginean in an article on the C/C++ Users Journal (December 2000). The same technique has been proposed for standardization (see N4189) but is still not part of the standard library. This technique employes RAII to execute a cleanup routine that is bound by scope ensuring the execution at scope exit unless released early. Here a simple C++ 14 implementation:

#include <cstdio>
#include <cstdlib>
#include <memory>

template<typename F>
class scope_guard {
public:
	// Prevent copying to avoid call destructor on each copy
	scope_guard(const scope_guard&) = delete;
	scope_guard& operator=(const scope_guard&) = delete;

	// Accept lvalue function objects
	scope_guard(const F& func)
		: rollback_func(func) {
		
	}
	
	// Accept rvalue function objects
	scope_guard(F&& func)
		: rollback_func(std::move(func)) {
		
	}

	// Allow moving
	scope_guard(scope_guard&& other)
		: rollback_func(std::move(func)), dismissed(other.dismissed) {
		other.dismissed = true;
	}

	// Invoke function object only if it hasn't been moved or manually dismissed
	~scope_guard() {
		if (!dismissed) {
			rollback_func();
		}
	}

	void dismiss() {
		dismissed = true;
	}
	
private:
	F rollback_func;
	bool dismissed = false;
};

template<typename F>
scope_guard<typename std::decay<F>::type> make_scope_guard(F&& f) {
	return scope_guard<typename std::decay<F>::type>(std::forward<F>(f));
}

bool foo() noexcept {
	std::cout << "foo!" << std::endl;
	return true;
}
void bar() noexcept {
	std::cout << "bar!" << std::endl;
}

class Func {
public:
	void operator()() const {
		std::cout << "Func object called!" << std::endl;
	}
};

void main() {
    auto scope_guard1 = make_scope_guard(foo);
	auto scope_guard2 = make_scope_guard(&bar);
	auto scope_guard3 = make_scope_guard(Func());
	Func f1;
	auto scope_guard4 = make_scope_guard(f1);
	auto scope_guard5 = make_scope_guard([]() {
		std::cout << "lambda called!" << std::endl;
	});
}

There is an interesting and alternative approach to achieve the same result without the need of creating an ad-hoc solution: use an std::unique_ptr.

std::unique_ptr is a template class with the following signatures:

template<class T, class Deleter = std::default_delete<T>>
//class unique_ptr;

template <class T, class Deleter>
//class unique_ptr<T[], Deleter>;

Focusing on the non-array version of std::default_delete we can observe that it is any functor/function that has the signature void operator()(T* ptr) const. A simple example of this, it can be the following:

using file_ptr = std::unique_ptr<FILE, decltype(&std::fclose)>;
{
   auto file = file_ptr(std::fopen(<somefile>, “r”), &std::fclose);
   //do something with file
}

Finally there is a handy way to release early the guard context: use the std::unique_ptr::release() function.