我正在构建一个将 std::vector<std::unique_ptr<A> >
作为参数的对象。构造函数是这样定义的
class B {
std::vector <std::unique_ptr<A> > e_;
public:
B(std::vector <std::unique_ptr<A> > e) : e_(std::move(e)){}
};
然后用作
std::vector <std::unique_ptr<A> > e;
B b(e);
并且 Xcode 显示错误
error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<A, std::__1::default_delete<A> >'
:new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
为什么即使我使用 std::move()
错误仍然存在?
编辑:如果我使用 B b(std::move(e))
而不是 B b(e))
,错误似乎消失了,有没有办法将 move
逻辑移动到函数的实现中?
原文由 Abhishek 发布,翻译遵循 CC BY-SA 4.0 许可协议
正如前面的答案所暗示的,问题在于您无法复制
std::unique_ptr
。按值传递构造函数参数将触发副本。话虽如此,如果意图是让B
拥有unique_ptr
,那么正确的方法是使用B b(std::move(e))
。这是 Herb Sutter 推荐的设计: https ://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/。通过值传递 unique_ptr 可以清楚地表明构造函数将对象的所有权从调用者手中夺走。此外,由于编译器需要明确的
std::move
,因此语义在代码中清楚地记录。也就是说,用户很清楚unique_ptr
由于显式std::move
被构造函数调用无效。