Bruice
Bruice

Reputation: 663

Function returns const ref to std::unique_ptr, can it return null?

I have a function that return const ref to a std::unique_ptr. I'm getting this ptr from some container. I want to have a possibility to return nullptr or something when in my container of std::unique_ptr there is no appropriate object to the input values. It seems to be impossible with const ref. There is definitely an option to return const raw pointer, but I would like to stick to std::unique_ptr if it's possible.

Upvotes: 0

Views: 1186

Answers (2)

Nicol Bolas
Nicol Bolas

Reputation: 473447

If you have an interface that returns a reference to an object, then that interface is referring to an object that exists somewhere in the program. If, in the course of trying to generate such a reference, you realize that the user has malformed their inputs or otherwise no such object exists, you have the following choices:

  1. Throw an exception. This is typically how we recognize cases where the user of a function did something wrong, that they asked for a thing that didn't exist.

  2. Change the function to return by value instead of by reference. In this case, it would probably be a naked pointer value, rather than a reference.

In any case, there is pretty much no reason to explicitly return an lvalue reference to a unique_ptr from any API. unique_ptr represents ownership, and if an API directly shows one, it should represent a transfer of ownership from the source to the destination. A function that returns an rvalue-reference to a unique_ptr means that it is giving the caller ownership of the object being pointed to.

If no transfer of ownership is taking place, you shouldn't be using unique_ptr in the API.

Note that there is a difference between a container that knows that it contains a unique_ptr and a container that happens to contain a unique_ptr. vector<T> is a generalized array, so the fact that operator[] returns a T& is OK even if that T happens to be unique_ptr. It is the user of the container who knows what that T means and how to use it.

By contrast, if your container is conceptually a container of unique_ptrs, then its API should recognize this fact.

Upvotes: 3

Dean Johnson
Dean Johnson

Reputation: 1852

class A {
public:
    const std::unique_ptr<B>& function() {
        return m_uni;
    }
private:
    std::unique_ptr<B> m_uni{nullptr};
};

This works and the returned unique_ptr is nullptr. Yes it is allowed and possible. Still, returning references to unique_ptr is kind of a code smell. If you can share more about why you want to use unique_ptr and what you are using this container for, someone may be able to provide an alternative.

The modifiers on the unique_ptr variable itself (const, &, *) have nothing to do with the value stored in the unique_ptr.

Upvotes: 2

Related Questions