C++将std::unique_ptr作为参数传递

3

我尝试使用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: 错误: 使用被删除的函数 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete<_Tp>]' tree.insert(tree.root, 10); ^ 在文件/usr/include/c++/4.9/bits/unique_ptr.h:356:7处声明 unique_ptr(const unique_ptr&) = delete; ^ BinTree.cpp:35:6: 错误: 初始化参数1时出错 'void BinTree::insert(std::unique_ptr&, T) [with T = int]' void BinTree::insert( ^ BinTree.cpp: 在对 'void BinTree::insert(std::unique_ptr&, T) [with T = int]' 的实例化中: BinTree.cpp:65:27: 从此处必需: required from here BinTree.cpp:40:47: 错误: 使用被删除的函数 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete<_Tp>]' if(node->data < key) insert(node->right, key); ^ 在文件/usr/include/c++/4.9/bits/unique_ptr.h:356:7处声明 unique_ptr(const unique_ptr&) = delete; ^ BinTree.cpp:35:6: 错误: 初始化参数1时出错 'void BinTree::insert(std::unique_ptr&, T) [with T = int]' void BinTree::insert( ^ BinTree.cpp:41:30: 错误: 使用被删除的函数 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = BinTreeNode; _Dp = std::default_delete<_Tp>]' else insert(node->left, key); ^ 在文件/usr/include/c++/4.9/bits/unique_ptr.h:356:7处声明 unique_ptr(const unique_ptr&) = delete; ^ BinTree.cpp:35:6: 错误: 初始化参数1时出错 'void BinTree::insert(std::unique_ptr&, T) [with T = int]' void BinTree::insert(

2
你忘了告诉我们错误信息。发生了什么?复制粘贴任何输出/错误,以便每个人都可以看到它。 - nos
3
std::unique_ptr 只能进行移动操作。 - LogicStuff
1个回答

6
错误是因为您试图从tree.root复制构造BinTree::insert的参数。std::unique_ptr是移动语义的。
我的猜测是BinTree::insert中的node应该通过引用传递。原因如下:
1. 如果通过值传递,您必须将tree.root std::move到它里面,这将窃取所有权。 2. 您在BinTree::insert中对其进行了移动赋值,这些更改不会传递给tree.root。

3
@tomtom,请确保你理解那里实际发生了什么。虽然LogicStuff的猜测很可能是正确的,但我不确定你是否完全理解其中的原因。 - SergeyA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接