So i'm trying to build a template class for binary trees.
I have a special way that i want to use to initialize the tree (which you can see in main()
).
The constructor works with shared_ptr
just fine, but i want to move it to more lightweight unique_ptr
, but i somehow get error-messages all over the place. Can someone explain how to get rid of the shared_ptrs?
Here is the working version with 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"));
}
I tried to just use unique instead of shared like that:
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) {}
};
But following compile-errors come up:
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;
^~~~~~~~~~
I guess it has to do with the deleted assignement-operator for unique_ptr
, and i have to use std::move()
sonmewhere, but i cant figure out where.
Thank you for your help!