Node doesn't need to befriend Tree since everything in Node is public from Tree's point of view.
You may as well get rid of your copy ctor for Node since it's just the default behaviour anyway, and nobody's likely to want to copy a Node.
Tree's ctor that takes a single value seems pointless. The initializer_list version handles that, it seems.
Your two XyzPrivate functions should be static.
1 2 3 4 5 6 7 8 9 10 11 12
void insert( T const& value )
{
insert_private( root, value );
}
staticvoid insert_private( Node*& curr, T const& value )
{
if ( !curr )
curr = new Node( value );
else
insert_private( value < curr->value ? curr->left : curr->right, value );
}
A non-static member function has a hidden parameter when called, i.e., the 'this' pointer that represents the object that it was called on. obj.func(x) gets converted under-the-hood to something like Object::func(&obj, x)
A static member function does not have this hidden parameter and therefore has no 'this' pointer. It is basically just a regular function that is within the namespace of the class (and that therefore also has implied "friend" access). It can be called in the same way, like obj.func(x), but in this case it translates into something like Object::func(x), with no obj parameter. In fact you could've just called it that way since it doesn't actually need an object.
> why was it crashing?
it was calling the copy-constructor, the default one provided by the compiler
so it was jus copying the pointers and you've got a double delete in the destructor