3

I tried to implement binary tree using std::unique_ptr but errors come up and I don't understand the output error.

The code is the following:

#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);
}

I assume the error is in insert function and is related to argument initialisation.

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(

2
  • 2
    You forgot to tell us the error. What's happening ? Copy paste any output/error so everyone can see it. Commented Dec 24, 2015 at 15:13
  • 3
    std::unique_ptr is move-only. Commented Dec 24, 2015 at 15:14

1 Answer 1

6

The error is caused by you trying to copy-construct the argument of BinTree::insert from tree.root. std::unique_ptr is move-only.

My guess is that node in BinTree::insert should be passed by reference. Reasons:

  1. You'd have to std::move the tree.root into it (if passed by value), which would steal the ownership
  2. You're move-assigning to it in BinTree::insert, these changes are not made to pass tree.root
Sign up to request clarification or add additional context in comments.

1 Comment

@tomtom, make sure you understand what is actually happening there. While LogicStuff is likely correct in their guess, I am not sure if you fully understand the reasons for that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.