I'm facing a compilation issue when defining a function that takes a move reference to a std::unique_ptr object.
#include <memory>
class foo {
public:
foo() { /* */ };
};
void function(foo&& arg) {
foo bar(arg);
}
void function2(std::unique_ptr<foo>&& arg){
std::unique_ptr<foo> foo(arg);
}
int main(int argc, char const *argv[]) {
foo A;
function(foo());
function2(std::unique_ptr<foo>(new foo));
return 0;
}
which leads to:
test.cpp: In function ‘void function2(std::unique_ptr<foo>&&)’:
test.cpp:16:30: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = foo; _Dp = std::default_delete<foo>]’
16 | std::unique_ptr<foo> foo(arg);
| ^
In file included from /usr/include/c++/9.3.0/memory:80,
from test.cpp:1:
/usr/include/c++/9.3.0/bits/unique_ptr.h:414:7: note: declared here
414 | unique_ptr(const unique_ptr&) = delete;
I've tried to replicate it by passing a reference to a custom class, but as expected it causes no issue as the default move constructor is implicitly declared by the compiler. Why does it happen then with std::unique_ptr? There is a default move constructor for std::unique_ptr, so what am I missing?
For safety reasons, some restrictions are imposed. A named variable will never be considered to be an rvalue even if it is declared as such. To get an rvalue, the function template std::move() should be used. Rvalue references can also be modified only under certain circumstances, being intended to be used primarily with move constructors.
void function2(std::unique_ptr<foo>&& arg) {
std::unique_ptr<foo> foo(std::move(arg));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With