I realize that similar questions have been asked elsewhere, but I couldn't find an answer that's a good fit for my function signatures.
Consider this typical pair of C functions:
int initFoo(Options options, Foo* foo);
void freeFoo(Foo* foo);
initFoo takes some options and a pointer to an uninitialized Foo struct. It initializes this struct and returns a result code that indicates whether the initialization was successful. freeFoo frees an initialized Foo struct.
Now assume I want to use these C functions in my C++ code. I want to use RAII, so I need to construct a unique_ptr<Foo> that will automatically call freeFoo on destruction. The best approach I could come up with is this:
template<typename T>
using lambda_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
lambda_unique_ptr<Foo> createFoo(Options options) {
Foo* foo = new Foo();
const int resultCode = initFoo(options, foo);
if (resultCode != 0) throw ...;
return lambda_unique_ptr<Foo>(foo, [](Foo* foo) {
freeFoo(foo);
delete foo;
});
}
I'm certain that there must be a more elegant solution. Ideally, something more functional that doesn't require so many individual steps. What I find particularly ugly is the necessity to explicitly allocate the Foo struct on the heap, then explicitly free and delete it in two steps. Any ideas?
allocFoonot really allocate Foo? It expects a pointer to an already-allocated Foo? DoesfreeFoonot free the memory?allocFootoinitFoo. And yes,initFooexpects a pointer to an existing struct.initFooandfreeFoodon't actually handle memory? They're like constructors and destructors for Foo?initFoo-unintFoo(no dynamic memory management) orallocFoo-freeFoo(both initialization / unitialization and dynamic memory management)freeFoonot free the memory? If it doesn't, I'd imagine the C code having as many steps as your C++ wrapper.