How to pass unique_ptr<T> in place of a raw *output* pointer parameter?

You can save one line of code (potentially many times) by writing many lines of code once:

class Wrapper
{
  std::unique_ptr<MyThing> &u;
  MyThing *p;

public:
  Wrapper(std::unique_ptr<MyThing> &u) : u(u), p() {}

  operator MyThing* & ()
  { return p; }

  ~Wrapper()
  { u.reset(p); }
};

Usage:

std::unique_ptr<MyThing> u;
CreateTheThing(Wrapper(u));

Is there a more direct method than this? One which doesn't require a temporary raw pointer?

No, there isn't.

Ideally, there would be a method of unique_ptr which exposes its internal pointer in a way that could work directly with the CreateTheThing method? unique_ptr::get() does not allow this, to my knowledge.

Your knowledge is correct. That would defeat the whole purpose of the std::unique_ptr, therefore unique_ptr::get() is a const function and the pointer is returned by value.

However similar as your constructor example, you can always use std::unique_ptr::reset() to pass an externally allocated pointer.

Also note: If the 3rd party API requires you to release the memory using free() you may need to provide a special deleter function for the std::unique_ptr.


If you use the function often you could put the conversion in a function.

Best would be to change the API, but this can also work.

inline std::unique_ptr<MyThing> CreateTheThing()
{
  MyThing* p;
  if (CreateTheThing(p))
  {
    return std::unique_ptr<MyThing>(p);
  }
  return std::unique_ptr<MyThing>();
}

You could also make this overload to make refactoring even easier:

inline bool CreateTheThing(std::unique_ptr<MyThing>& ptr)
{
    try 
    {
        MyThing* p;
        if (CreateTheThing(p))
            ptr = std::unique_ptr<MyThing>(p);
        else
            return false;
    }
    catch (std::bad_alloc&)
    {
        return false;
    }
    return true;
}