This also works well with a C++ `defer` helper. #define CONCAT_LITERAL(x, y) x ## y #define CONCAT(x, y) CONCAT_LITERAL(x, y) template struct DeferWrapper { F f; DeferWrapper(F f) : f(f) {} ~DeferWrapper() { f(); } }; template DeferWrapper deferWrapper(F f) { return DeferWrapper (f); } #define defer(code) auto CONCAT(_defer_, __COUNTER__) = deferWrapper([&]() code) Example of usage: { Foo *foo; if (initializeFoo()) {…
You're turning RAII upside down... Learn to use proper RAII and you won't need this defer hack.
I fail to see how "learning proper RAII":
struct FooWrapper {
Foo *foo;
FooWrapper(...) {
foo = initializeFoo(...);
if (!foo)
throw FooException(...);
}
~FooWrapper() {
destroyFoo(foo);
}
}
try {
FooWrapper fooWrapper(...);
}
catch (FooException &e) {
...
}
is easier than Foo *foo;
if (initializeFoo(foo, ...)) {
...
}
defer({
destroyFoo(foo);
})
If this isn't what you meant, could you demonstrate?