Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not to accept std::unique_ptr by rvalue reference?

Tags:

c++

Can somebody explain why everybody passes std::unique_ptr by value instead of by rvalue reference?

From what I've observed, this required an additional move constructor to be invoked.

Here's an example of a class holding a "pointer". It takes 3 move-ctor calls to take it by value, versus 2 calls to take it by reference:

#include <memory>
#include <iostream>

class pointer {
public:
    pointer()
    { std::cerr << "ctor" << std::endl; }
    
    pointer(const pointer&)
    { std::cerr << "copy-ctor" << std::endl; }
    
    pointer& operator=(const pointer&)
    { std::cerr << "copy-assignment" << std::endl; return *this; }
    
    pointer(pointer&&)
    { std::cerr << "move-ctor" << std::endl; }
    
    pointer& operator=(pointer&&)
    { std::cerr << "move-assignment" << std::endl; return *this; }
    
    ~pointer()
    { std::cerr << "dtor" << std::endl; }
};

class A {
public:
    // V1
    A(pointer _ptr) : ptr(std::move(_ptr)) {}
        
    // V2
    A(pointer&& _ptr) : ptr(std::move(_ptr)) {}

private:
    pointer ptr;
};

int main() {
    // Three calls to move-ctor versus two calls if pass by rvalue reference
    auto ptr = pointer();
    A a(std::move(ptr));

    // Two calls to move-ctor always
    A a(pointer{});
}
like image 743
banana36 Avatar asked Mar 03 '26 21:03

banana36


1 Answers

Passing a unique_ptr by reference, rvalue or otherwise, doesn't actual move anything, so you can't know by just looking at the function declaration if a move will happen.

Passing a unique_ptr by value on the other hand guarantees that the passed in pointer will be moved from, so without even have to look at the documentation you know calling that function releases you from the pointers' ownership.

like image 156
NathanOliver Avatar answered Mar 06 '26 10:03

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!