[英]“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.