![](/img/trans.png)
[英]“error: use of deleted function” when calling std::move on unique_ptr in move constructor
[英]Initializing unique_ptr causes an "error: use of deleted function" even though it's "std::move"ed
我正在编写将std::unique_ptr
传递给看起来很糟糕的几层的代码,但我别无选择,只能暂时传递它。
问题是当我尝试将std::unique_ptr
传递给Provider
类的构造函数时出现错误。 在调用Child::function1()
时, Child
已使用Impl&
和std::unique_ptr<Retriever>
的参数从其他地方初始化/构造。
有人可以告诉我为什么会出现此错误,以及如何完成这项工作吗? 我想知道这是否是因为发生了继承,但我不知道除了移动来完成这项工作之外还能做什么......(除了不通过所有这些看起来相似的类传递这个 ptr使用相同的构造函数...大声笑)
// child.cpp
Child::Child(Impl& child_impl, std::unique_ptr<Retriever> child_retriever_up)
: Parent(child_impl, std::move(child_retriever_up))
{}
T::Y Child::function1() const
{
**Provider provider(d_impl, d_retriever_up);**
// these d_impl and d_retriever are in Parent class.
...
return Y;
}
// child.h
class Child : public Parent {
public:
// creators
explicit Child(Impl& child_impl, std::unique_ptr<Retriever> child_retriever_up);
~Child() override = default;
// accessors
T::Y Child::function1() const;
private:
Child(const Child&) = delete;
Child& operator=(const Child&) = delete;
// parent.cpp
Parent::Parent(Impl& impl, std::unique_ptr<Retriever> retriever_up)
: d_impl(impl), d_retriever_up(std::move(retriever_up))
{}
// parent.h
class Parent {
public:
// creators
explicit Parent(Impl& impl, std::unique_ptr<Retriever> retriever_up);
virtual ~Parent() = default;
// copy constructor
Parent(const Parent& parent)
: d_context(parent.d_impl)
, d_retriever_up(std::move(*parent.d_retriever_up))
{
}
// data
Impl& d_impl;
std::unique_ptr<Retriever> d_retriever_up;
private:
//Parent(const Parent&) = delete;
Parent& operator=(const Parent&) = delete;
// provider.cpp
Provider::Provider(Impl& impl, std::unique_ptr<Retriever> retriever_up)
: d_impl(impl)
, d_retriever(std::move(retriever_up))
{}
// provider.h
class Provider {
public:
Provider(Impl& context, std::unique_ptr<Retriever> retriever_up);
//copy contstructor
Provider(const Provider& provider)
: d_impl(provider.d_impl)
, d_retriever(std::move(*provider.d_retriever))
{
}
private:
Impl& d_impl;
std::unique_ptr<Retriever> d_retriever;
}
在Child::function1()
中,您将d_retriever_up
按值传递给Provider
构造函数。 这需要制作d_retriever_up
的副本,这是不可能的,因为它是一个unique_ptr
,它具有delete
'd 其复制构造函数,因此会出现错误。
您需要使用std::move()
将d_retriever_up
移动到Provider
。 你声称正在这样做,但你不是,至少不是在所有需要它的地方。 将调用者的unique_ptr
移入Provider
构造函数的retriever_up
参数与将retriever_up
参数移入Provider
的d_retriever
类成员是一个单独的操作。
但是,在你修复它之后,你会遇到另一个问题。 Child::function1()
被标记为const
,这使得在该上下文中对d_retriever_up
的访问为const
,因此function1()
不能修改d_retriever_up
,包括移动(因为移动unique_ptr
会将其持有的指针设置为nullptr
)。
因此,要使代码正常工作,您需要删除const
并添加std::move()
:
T::Y Child::function1()
{
Provider provider(d_impl, std::move(d_retriever_up));
...
return Y;
}
话虽如此,在您的设计中移动d_retriever_up
是有问题的。 您可能需要考虑改用std::shared_ptr
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.