10.1 Passing const unique_ptr by reference

#1

In 10.1 the method signature to check if a BST is balanced is

bool IsBalanced(const unique_ptr<BSTNode<int>>& tree) { }

Isn’t this poor form? Herb Sutter states that “An object of type std::unique_ptr should be passed as a non-const reference, or by value. Passing by non-const reference signifies that the parameter is an in/out parameter. Passing by value signifies that the parameter is a sink (i.e. takes ownership and does not return it). A const reference std::unique_ptr parameter provides no benefits and restricts the potential callers of the function.” [1]

Shouldn’t we really just have unique_ptr<BSTNode<int>>& ?

0 Likes

#2

it shouldn’t be passed by non-const unique_ptr ref because it’s not an in/out parameter (receiving function does not modify the unique_ptr; and we don’t want it to) nor by unique_ptr value because it’s not a sink (the receiving function doesn’t take the ownership of the unique_ptr).

Herb Sutter discourages const unique_ptr ref because it doesn’t make sense to restrict the input parameter lifetime to be managed by a unique_ptr here. it should be able to accept the parameter that’s managed by shared_ptr or raw pointers too.

so Herb Sutter actually recommends using a raw pointer in such case (in the same link)

Passing a const unique_ptr& is strange because it can accept only either null or a widget whose lifetime happens to be managed in the calling code via a unique_ptr, and the callee generally shouldn’t care about the caller’s lifetime management choice. Passing widget* covers a strict superset of these cases and can accept “null or a widget” regardless of the lifetime policy the caller happens to be using.

Guideline: Don’t use a const unique_ptr& as a parameter; use widget* instead.

…which makes sense; anyways, at the very least, it shouldn’t be non-const unique_ptr ref for reasons stated above.

0 Likes

#3

Thanks @xjis that definitely helps my understanding of unique_ptr lifetimes. I keep seeing that raw pointers should stop being used but it seems like there’s still a place for them in many areas of modern C++.

0 Likes

#4

In our application, we might just read the value of an unique_ptr and produce the output, and it fits the situation of const reference of an unique_ptr since the function is a read-only function, and this function does not own the ownership of unique_ptr.

1 Like