Reputation: 802
Can I pass a unique_ptr's reference to a function? If not why should I avoid it?
Ex:
void func(unique_ptr<Clss>& ref);
main() {
unique_ptr<Clss> a = std::make_unique<Clss>();
fn(a);
}
Upvotes: 7
Views: 18450
Reputation: 802
According to Herb Sutter:
https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/
Passing unique_ptr by reference is for in/out unique_ptr parameters.
void f( unique_ptr<widget>& ); // (d)
This should only be used to accept an in/out unique_ptr
, when the function is supposed to actually accept an existing unique_ptr
and potentially modify it to refer to a different object. It is a bad way to just accept a widget, because it is restricted to a particular lifetime strategy in the caller.
Thanks @sgvd
Upvotes: 6
Reputation: 40150
Passing a std::unique_ptr
to a function is perfectly fine as long as you respect the same rules you would when passing a regular reference to a function:
std::unique_ptr
and the object it points to must live at least as long as the function will use the reference;Upvotes: 0
Reputation: 5166
See this code snippet, two ways of passing unique_ptr as function parameter. fun1 will take ownership of the object ( hence should be forwarded from the caller) but func2 commits thats the reference unique_ptr object will be passed as reference and will not be modified by the function.
void func1(unique_ptr<Clss>&& moved_obj) // this function takes ownership
{
//do something with the moved_obj
moved_obj.reset();
}
void func2(const unique_ptr<Clss>& ref_obj) // this function takes reference
{
unique_ptr<Clss> new_obj = std::make_unique<Clss>(*(ref_obj));
}
int main() {
unique_ptr<Clss> a = std::make_unique<Clss>();
func1(std::move(a));
unique_ptr<Clss> b = std::make_unique<Clss>();
func2(b);
return 0;
}
Upvotes: 3
Reputation: 218238
I see those valid meaningful signatures:
void take_ownership(std::unique_ptr<Clss>);
// or void take_ownership(std::unique_ptr<Clss>&&);
void use(/*const*/ Clss*);
// or void use(/*const*/ Clss&);
std::unique_ptr<Clss> create(/*args..*/);
void might_take_ownership(std::unique_ptr<Clss>&);
The later might make sense, but it is more difficult to reason with (as any I/O argument).
If you can, prefer one of the other.
Upvotes: 2
Reputation: 93364
Can I pass a unique_ptr's reference to a function?
Yes, a unique_ptr
is class like any other.
You should do this when you want to mutate an existing unique_ptr
from a function (e.g. calling .reset()
on it).
If only you want to access the object inside unique_ptr<T>
, take T&
or const T&
in your function interfaces, so that they can be used independently of unique_ptr
.
Upvotes: 8