简体   繁体   中英

Passing std::unique_ptr to constructor to take ownership

I want to pass a std::unique_ptr to the constructor of a class that will take ownership of the data owned by the std::unique_ptr .

Are there any differences between the approaches foo and bar below in terms of how the compiler handles them that would make one of them preferable?

foo class:

template <class T>
class foo
{
    std::unique_ptr<T> data_;

public:
    foo(std::unique_ptr<T>&& data) :
        data_{ std::forward<std::unique_ptr<T>>(data) }
    {
    }
};

bar class:

template <class T>
class bar
{
    std::unique_ptr<T> data_;

public:
    bar(std::unique_ptr<T> data) :
        data_{ std::move(data) }
    {
    }
};

Binding to a reference requires one less move:

void f(std::unique_ptr<T>&& p) { g(std::move(p)); }

f(std::make_unique<T>());  // no move, g binds directly to the temporary

Binding to an object parameter requires one actual move:

void f(std::unique_ptr<T> p) { g(std::move(p)); }

f(std::make_unique<T>());  // p constructed (= moved) from temporary,
                           // g binds to p

The extra move involves one pointer copy, one setting of a pointer to null, and one destructor with a condition check. This is not a big cost, and the question of which style to use depends on the kind of code you're writing:

The more leaf your code is and the less it is used, the more the simple version with by-value passing buys you simplicity. Conversely, the more library your code is and the less you know your users, the more there is value in not imposing avoidable cost, no matter how small.

You decide.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM