Smart pointers with functions returning a pointer in an argument

Viewed 106

This question was discussed a few times but all those discussions almost a decade old and there was no good solution. The question is the same.

We have smart pointers, like unique_ptr, that is great. We have tons of C functions returning a pointer to an object as an argument which later needs to be released.

Let's say this is the function:

int CreateSomething(OBJECT_TYPE** pObject);

So, what would we normally do without smart pointers? Apparently something like that:

OBJECT_TYPE* pObject;
if(CreateSomething(&pObject) == 0) {
    // Use the pObject pointer
    delete pObject;
}

Now, I would like to rewrite it using smart pointers, and I would like it to be as simple as this:

unique_ptr<OBJECT_TYPE> pObject;
if(CreateSomething(&pObject) == 0) {
    // Use the pObject pointer
}

Technically, that would be quite possible if unique_ptr would have T** operator&, and if it would count on this kind of workflow, but it doesn't.

In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer. But those extra steps can and should be eliminated, and I hope that maybe there is already an implementation which would allow me to do what I need in that simple manner as I showed.

Yes, I can write my own smart pointer or mediator, which would simplify the usage of unique_ptr, but first I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?

3 Answers

C++23 has very recently added std::out_ptr for exactly this use case.

write a wrapper: (uncompiled code)

namespace smart_ptrs {
std::unique_ptr<OBJECT_TYPE> CreateSomething() {
    OBJECT_TYPE *p = nullptr;
    if (::CreateSomething(&p))
      return std::unique_ptr<OBJECT_TYPE>(p);
    return std::unique_ptr<OBJECT_TYPE>();
}

Then you can write:

std::unique_ptr<OBJECT_TYPE> ptr = smart_ptrs::CreateSomething();
if (ptr) {
   // Use the pObject pointer
   }

In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer.

Basically, yes. That is exactly what you must do (for now anyway, until std::out_ptr is added in C++23).

C++ smart pointers simply do not expose access to their held pointer, thus no way for you to obtain its address to pass to the C function. So, you have to use the smart pointer's constructor or assignment operator instead, which requires the object pointer to already be initialized first.

I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?

You have not overlooked anything.

Related