C++ 将 std::unique_ptr 作为参数传递
C++ passing std::unique_ptr as an argument
我尝试使用 std::unique_ptr
实现二叉树,但出现错误,我不明白输出错误。
代码如下:
#include <iostream>
#include <memory>
#include <functional>
#include <utility>
template <typename T>
class BinTreeNode {
public:
BinTreeNode(T key): data {key}, left {nullptr}, right {nullptr} {}
~BinTreeNode() {}
T data;
std::unique_ptr<BinTreeNode<T>> left;
std::unique_ptr<BinTreeNode<T>> right;
};
template <typename T>
class BinTree {
public:
BinTree() : root {nullptr} {}
~BinTree() {}
std::unique_ptr<BinTreeNode<T>> root;
void insert(std::unique_ptr<BinTreeNode<T>> node, T key);
};
template <typename T>
void BinTree<T>::insert(
std::unique_ptr<BinTreeNode<T>> node,
T key)
{
if(node){ // != nullptr
if(node->data < key) insert(node->right, key);
else insert(node->left, key);
}
else{
std::unique_ptr<BinTreeNode<T>> u_ptr(new BinTreeNode<T>(key));
node = std::move(u_ptr);
}
}
int main(){
BinTree<int> tree();
tree.insert(tree.root, 10);
}
我假设错误出在插入函数中并且与参数初始化有关。
BinTree.cpp:65:27: error: use of deleted function
‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp,
_Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’ tree.insert(tree.root, 10);
^
In file included from /usr/include/c++/4.9/memory:81:0,
from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void
BinTree::insert(std::unique_ptr >, T) [with T =
int]’ void BinTree::insert(
^
BinTree.cpp: In instantiation of ‘void
BinTree::insert(std::unique_ptr >, T) [with T =
int]’: BinTree.cpp:65:27: required from here BinTree.cpp:40:47:
error: use of deleted function ‘std::unique_ptr<_Tp,
_Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’
if(node->data < key) insert(node->right, key);
^
In file included from /usr/include/c++/4.9/memory:81:0,
from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void
BinTree::insert(std::unique_ptr >, T) [with T =
int]’ void BinTree::insert(
^
BinTree.cpp:41:30: error: use of deleted function
‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp,
_Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’ else insert(node->left,
key);
^
In file included from /usr/include/c++/4.9/memory:81:0,
from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void
BinTree::insert(std::unique_ptr >, T) [with T =
int]’ void BinTree::insert(
错误是由于您试图从 tree.root
复制构造 BinTree::insert
的参数造成的。 std::unique_ptr
只能移动。
我的猜测是 BinTree::insert
中的 node
应该通过引用传递。原因:
- 您必须
std::move
将 tree.root
放入其中(如果按值传递),这会窃取所有权
- 您在
BinTree::insert
中对其进行移动分配,这些更改不会通过 tree.root
我尝试使用 std::unique_ptr
实现二叉树,但出现错误,我不明白输出错误。
代码如下:
#include <iostream>
#include <memory>
#include <functional>
#include <utility>
template <typename T>
class BinTreeNode {
public:
BinTreeNode(T key): data {key}, left {nullptr}, right {nullptr} {}
~BinTreeNode() {}
T data;
std::unique_ptr<BinTreeNode<T>> left;
std::unique_ptr<BinTreeNode<T>> right;
};
template <typename T>
class BinTree {
public:
BinTree() : root {nullptr} {}
~BinTree() {}
std::unique_ptr<BinTreeNode<T>> root;
void insert(std::unique_ptr<BinTreeNode<T>> node, T key);
};
template <typename T>
void BinTree<T>::insert(
std::unique_ptr<BinTreeNode<T>> node,
T key)
{
if(node){ // != nullptr
if(node->data < key) insert(node->right, key);
else insert(node->left, key);
}
else{
std::unique_ptr<BinTreeNode<T>> u_ptr(new BinTreeNode<T>(key));
node = std::move(u_ptr);
}
}
int main(){
BinTree<int> tree();
tree.insert(tree.root, 10);
}
我假设错误出在插入函数中并且与参数初始化有关。
BinTree.cpp:65:27: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’ tree.insert(tree.root, 10); ^
In file included from /usr/include/c++/4.9/memory:81:0, from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; ^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void BinTree::insert(std::unique_ptr >, T) [with T = int]’ void BinTree::insert( ^
BinTree.cpp: In instantiation of ‘void BinTree::insert(std::unique_ptr >, T) [with T = int]’: BinTree.cpp:65:27: required from here BinTree.cpp:40:47: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’
if(node->data < key) insert(node->right, key); ^In file included from /usr/include/c++/4.9/memory:81:0, from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; ^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void BinTree::insert(std::unique_ptr >, T) [with T = int]’ void BinTree::insert( ^
BinTree.cpp:41:30: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete >]’ else insert(node->left, key); ^
In file included from /usr/include/c++/4.9/memory:81:0, from BinTree.cpp:2: /usr/include/c++/4.9/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; ^
BinTree.cpp:35:6: error: initializing argument 1 of ‘void BinTree::insert(std::unique_ptr >, T) [with T = int]’ void BinTree::insert(
错误是由于您试图从 tree.root
复制构造 BinTree::insert
的参数造成的。 std::unique_ptr
只能移动。
我的猜测是 BinTree::insert
中的 node
应该通过引用传递。原因:
- 您必须
std::move
将tree.root
放入其中(如果按值传递),这会窃取所有权 - 您在
BinTree::insert
中对其进行移动分配,这些更改不会通过tree.root