[英]recreate(reassign) a std::shared_ptr or std::unique_ptr
[英]How to convert from std::shared_ptr to std::unique_ptr?
所以我正在嘗試為二叉樹構建模板 class 。 我有一種特殊的方式,我想用它來初始化樹(你可以在main()
中看到)。
構造函數與shared_ptr
一起工作得很好,但我想將它移動到更輕量級的unique_ptr
,但我不知何故得到了錯誤消息。 有人可以解釋如何擺脫 shared_ptrs 嗎? 這是帶有 shared_ptr 的工作版本:
#include <optional>
#include <memory>
#include <string>
template <class C>
class node{
private:
C label;
std::shared_ptr<node<C>> left;
std::shared_ptr<node<C>> right;
public:
node(const C& name,
const std::optional<node<C>>& leftChild = {},
const std::optional<node<C>>& rightChild = {}) :
label(name),
left(leftChild ? std::make_shared<node<C>>(*leftChild) : nullptr),
right(rightChild ? std::make_shared<node<C>>(*rightChild) : nullptr) {}
};
int main(){
using sNode = node<std::string>;
auto root = std::make_unique<sNode>("root", sNode("left", sNode("left.left")), sNode("right"));
}
我試圖只使用獨特的而不是這樣的共享:
template <class C>
class node{
private:
C label;
std::unique_ptr<node<C>> left;
std::unique_ptr<node<C>> right;
public:
node(const C& name,
const std::optional<node<C>>& leftChild = {},
const std::optional<node<C>>& rightChild = {}) :
label(name),
left(leftChild ? std::make_unique<node<C>>(*leftChild) : nullptr),
right(rightChild ? std::make_unique<node<C>>(*rightChild) : nullptr) {}
};
但是出現以下編譯錯誤:
In file included from /usr/include/c++/7/memory:80:0,
from binaryTree.hpp:2,
from main.cpp:1:
/usr/include/c++/7/bits/unique_ptr.h: In instantiation of ‘typename std::_MakeUniq<_Tp>::__single_object std::make_unique(_Args&& ...) [with _Tp = node<std::__cxx11::basic_string<char> >; _Args = {const node<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >&}; typename std::_MakeUniq<_Tp>::__single_object = std::unique_ptr<node<std::__cxx11::basic_string<char> >, std::default_delete<node<std::__cxx11::basic_string<char> > > >]’:
binaryTree.hpp:15:51: required from ‘node<C>::node(const C&, const std::optional<node<C> >&, const std::optional<node<C> >&) [with C = std::__cxx11::basic_string<char>]’
main.cpp:7:80: required from here
/usr/include/c++/7/bits/unique_ptr.h:825:30: error: use of deleted function ‘node<std::__cxx11::basic_string<char> >::node(const node<std::__cxx11::basic_string<char> >&)’
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from main.cpp:1:0:
binaryTree.hpp:5:7: note: ‘node<std::__cxx11::basic_string<char> >::node(const node<std::__cxx11::basic_string<char> >&)’ is implicitly deleted because the default definition would be ill-formed:
class node{
^~~~
binaryTree.hpp:5:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = node<std::__cxx11::basic_string<char> >; _Dp = std::default_delete<node<std::__cxx11::basic_string<char> > >]’
In file included from /usr/include/c++/7/memory:80:0,
from binaryTree.hpp:2,
from main.cpp:1:
/usr/include/c++/7/bits/unique_ptr.h:388:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
In file included from main.cpp:1:0:
binaryTree.hpp:5:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = node<std::__cxx11::basic_string<char> >; _Dp = std::default_delete<node<std::__cxx11::basic_string<char> > >]’
class node{
^~~~
In file included from /usr/include/c++/7/memory:80:0,
from binaryTree.hpp:2,
from main.cpp:1:
/usr/include/c++/7/bits/unique_ptr.h:388:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
我想這與unique_ptr
的已刪除分配運算符有關,我必須使用std::move()
sonmewhere,但我不知道在哪里。 謝謝您的幫助!
但我不知何故到處都收到錯誤消息。 有人可以解釋如何擺脫 shared_ptrs 嗎?
unique_ptr
不可復制,只能移動。 這意味着一旦您在 class 中放入unique_ptr
成員, node
就不能再被復制:編譯器為您生成的隱式復制分配和構造函數將不再存在。
所以你必須決定你希望你的 class 如何表現。
如果您希望您的node
是可復制的,您必須自己實現復制操作(您必須深度克隆樹)。 這將為您提供價值語義。
否則,如果您不希望node
可復制,您仍然需要在構造函數中執行node
對象的深度克隆。 原因是,由於您正在傳遞const
引用,因此您無法獲得它們的 memory 的所有權(並且您想要它們const
因為您可能希望能夠傳遞臨時變量)。
或者您可以更改您的界面以避免參考。 相反,采用接收器參數(即按值)並將它們移動到您的構造函數中。 (@rafix07 在答案中寫了這個,但現在被刪除了)。 您甚至可以對name
參數執行此操作:
node(C name, std::optional<node<C>> leftChild = {}, std::optional<node<C>> rightChild = {}): label(std::move(name)), left(leftChild? std::make_unique<node<C>>( std::move(*leftChild) ): nullptr), right(rightChild? std::make_unique<node<C>>( std::move(*rightChild) ): nullptr) {}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.