【发布时间】:2020-08-17 04:01:46
【问题描述】:
在定义一个对std::unique_ptr 对象进行移动引用的函数时,我遇到了编译问题。
#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;
}
导致:
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;
我尝试通过传递对自定义类的引用来复制它,但正如预期的那样,它不会导致任何问题,因为默认移动构造函数是由编译器隐式声明的。为什么std::unique_ptr会发生这种情况? std::unique_ptr 有一个默认的移动构造函数,那么我缺少什么?
【问题讨论】:
-
function2 更好的签名是
void function2(std::unique_ptr<foo> arg),因为它会下沉(移动)持有的对象,如果使用不正确,unique_ptr 会在调用点提供编译器错误反馈。 (std::unique_ptr<foo>&&也是如此,但随后 function2 可能决定不移动参数而不是移动参数。)对于像std::vector这样的容器作为接收器 arg,我会使用std::vector<foo>&&作为参数,因为否则调用站点可能会默默地制作一个可能很昂贵的副本。
标签: c++ constructor smart-pointers move-semantics