4 ms·
This is a reasonable suggestion since the code isn't too bad. std::unique_ptr<Foo, std::function<void(Foo*)>> p(new Foo, [](Foo* p) { if (p) destro
by vortico 9y ago
This is a reasonable suggestion since the code isn't too bad.
std::unique_ptr<Foo, std::function<void(Foo*)>> p(new Foo, [](Foo* p) {
if (p) destroyFoo(p);
});
// initialize Foo and set to NULL if failed
It increases complexity a bit because you no longer have a simple pointer, and you can't allocate on the stack anymore (my example should have declared `Foo foo;` with `destroyFoo(&foo)`, sorry for typo.)
- contravariant 9y agoIf you didn't want a pointer you could have just used something like: template<typename TFoo, typename TDestr> struct FooWrapper { TFoo foo; const TDestr destroyFoo; template<typename TInit> FooWrapper(Tinit initializeFoo, TDestr destroyFoo) : destroyFoo(destroyFoo) { foo = initializeFoo(); if (!foo) throw FooException(...); } ~FooWrapper() { destroyFoo(&foo); } } Although really that should have been part of the "Foo" class itself, but if you need to deal with external code I suppose that might not be possible.
- vortico 9y agoOh yes, I forgot to make it clear that `Foo` is a C struct from a C API. There are tens of thousands of such libraries. An issue with your wrapper is that it is not generic enough and thus must be written for each Foo-like object. That could likely be fixed with more template arguments, but of course there are multiple ways to initialize C objects like - `fooInitialize(Foo foo); // expects that foo is pre-allocated` - `fooInitialize(Foo foo); // allocates and sets the Foo pointer. Annoying, but some libraries do this.` - `Foo fooInitialize(...); // taking certain arguments` A single `defer` wrapper allows you implement custom destruction behavior for each instance, which is useful if you want to set flags or log errors in the destruction process.
- contravariant 9y agoWell you probably have your reasons for needing an absurdly general method of handling things. That said I think it would be a lot cleaner to use locally define a class that takes care of both initialisation and destruction when possible, rather than one that only takes care of the destruction. I wouldn't mind too much if you used macros to simplify the boiler plate somewhat. What worries me is that using 'defer' leaves absolutely no possibility for reusing the code, other than by literally copy pasting it, which just rubs me the wrong way. It goes completely against the DRY principle.