How can I pass a unique pointer as a function parameter?

I have a very simple code just to illustrate what's going on:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <memory>

class Object
{
    public: 
        Object() = default;
        ~Object() = default;

        void SetValue( int val )
        {
            mValue = val;
        }

        void PrintValue()
        {
            std::cout << this->mValue << std::endl;
        }

    private:
        int mValue;
};

void ReadObject( Object* obj )
{
    obj->PrintValue();
}

int main()
{
    std::unique_ptr<Object> mObject = std::make_unique<Object>();
    mObject->SetValue( 200 );

    ReadObject( mObject ); // ERROR
    return 0;
}

Passing mObject to ReadObject gives me an error that reads: no suitable conversion function from "std::unique_ptr<Object,std::default_delete<Object>>" to "Object *" exists

I've seen that people use std::move() but I'm not sure why or if that will mess up ownership of the original mObject because I want it to be the same... Maybe I'm just confused as to how unique pointers work?...
Thanks for taking the time!
Last edited on
Your function's parameter is a regular pointer, not a unique pointer.

Line 24 should be:
void ReadObject( std::unique_ptr<Object> obj )

And when you want to pass the unique pointer you have to move it (line 34):
ReadObject( std::move(mObject) );

Fair warning, once you move your unique pointer into the function the unique pointer in main is no longer a valid smart pointer. If you want to continue using it in main passing as a reference would be the thing to do (line 24):
void ReadObject( std::unique_ptr<Object>& obj )

Passing by reference you don't have to move the unique pointer, you can call the function as you do in line 34.

https://www.internalpointers.com/post/move-smart-pointers-and-out-functions-modern-c

That link covers how to pass all smart pointers to a function.

You could retain most of what you've written so far and just modify line 34 to pass as raw pointer the stored pointer:
ReadObject( mObject.get() );
You could retain most of what you've written so far and just modify line 34 to pass as raw pointer the stored pointer:

That's what you should do. Or call move to give ownership of the pointed-to object to the function.

Passing a reference to unique_ptr<T> is akin to passing a T*&, not something that should be done unless there's interest in the pointer, and not merely the pointed-to object.

It's reminiscent of C programmers who are so hung up on pointers that when they have a pointer they need to move around they pass a pointer to it:
void f(char **pstr) { if (pstr) puts(*pstr); }
Not wrong, but confusing and detrimental to performance.

Cases where this is desirable include strtod, etc. The C++ version of this advice is in @Furry Guy's link.
Last edited on
Ok I understand now!.. I appreciate the help and thanks a lot for the tips and the heads up!
Topic archived. No new replies allowed.