#include <iostream>
#include <algorithm>
#include <stdexcept>

/*
 *  Hilfskonstrukte
 */

template <typename F>
class CleanupHelper {
	public:
		CleanupHelper (F f) : m_f (std::move (f)) {}
		~CleanupHelper () { m_f (); }
	private:
		F m_f;
};

template <typename F>
CleanupHelper<F> cleanup (F f) { return { std::move (f) }; }

/*
 * Usercode
 */
 
void tuwas () {
	std::cout << "Hole a\n";
	int a = 42; // a holen
	if (a == 0) throw std::runtime_error ("A initialization failed");
	auto cleanA = cleanup ([&] () { std::cout << "Cleaning A\n"; });
	
	std::cout << "Hole b\n";
	int b = 3; // b holen
	if (b == 0) throw std::runtime_error ("B initialization failed");
	auto cleanB = cleanup ([&] () { std::cout << "Cleaning B\n"; });
	
	std::cout << "Hole c\n";
	int c = 0; // c holen
	if (c == 0) throw std::runtime_error ("C initialization failed");
	auto cleanC = cleanup ([&] () { std::cout << "Cleaning C\n"; });
}

int main() {
	try {
		tuwas ();
	} catch (std::exception& e) {
		std::cout << "Error: " << e.what () << std::endl;
	}
	return 0;
}