我正在构造一个以a 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)){}
};
Run Code Online (Sandbox Code Playgroud)
然后用作
std::vector <std::unique_ptr<A> > e;
B b(e);
Run Code Online (Sandbox Code Playgroud)
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)...);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`
Run Code Online (Sandbox Code Playgroud)
为什么即使我正在使用,错误仍然持续存在std::move()?
编辑:如果我使用B b(std::move(e))而不是错误似乎消失B b(e)),有没有办法将move逻辑移至函数的实现?
正如前面的答案所暗示的,问题是您无法复制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。
您的构造函数参数是按值传递的值,该值将进行复制,但是您不能复制std :: unique_ptr。通过引用应该可以工作:
class B {
std::vector <std::unique_ptr<float> > e_;
public:
B(std::vector <std::unique_ptr<float> >& e) : e_(std::move(e)){}
};
Run Code Online (Sandbox Code Playgroud)
但是...我同意其他意见,认为这是不良设计。如果您想B拥有e但也想在其e外部进行操作,B那么它应该是公共成员,不需要花哨的构造函数:
class B {
public:
std::vector <std::unique_ptr<float> > e_;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
14906 次 |
| 最近记录: |