While implementing a BS Tree, I noticed some things that I wasn't so sure about since I started using C++11 smart pointers and it makes me wonder why it is so. The code below works fine if I use init-brace pairs{} instead of the parentheses; my personal rule is to value initialize every member(directly or through a ctor) and since Node::right and Node::left are both smart pointers, therefore, nullptr it is. Question 1: Why does the parentheses fail and init-brace pairs succeed? In this case ONLY, is there any semantic difference between the two?
In BST, in the ctor that takes an std::initializer_list, I understand that std::initializer_list elements are only copyable, according to this. So if I'm not wrong, according to Scott Meyer at the recent GN13, performing a move on a const object would only trigger the copy-ctor of the object.
Quesion 2 Why does the compiler fail to copy the object at the call to BST::insert( T&& ) ?
#include <memory>
template<typename T>
struct Node
{
//~ std::unique_ptr<Node<T>> left ( nullptr ), right ( nullptr );
std::unique_ptr<Node<T>> left { nullptr }, right { nullptr };
Node<T> *parent = nullptr;
T value { };
Node<T> () = default;
Node<T> ( T && val, Node<T> * _left = nullptr, Node<T> *_right = nullptr,
Node<T> *_parent = nullptr ): left( _left ), right ( _right ), parent( _parent ),
value ( std::move( val ) )
{
}
};
template<typename T>
struct BinarySearchTree
{
std::unique_ptr<Node<T>> root;
BinarySearchTree(): root { nullptr } { }
BinarySearchTree( std::initializer_list<T> && lst ): BinarySearchTree { }{
//If the below code were changed to
//~ for( auto && i: lst ){ it would be an error
for( typename std::remove_reference<typename std::remove_const<T>::type>::type i: lst ){
this->insert( std::move( i ) );
}
}
void insert( T && v ) { }
};
int main(){
BinarySearchTree<int> a { 11, 24 };
return 0;
}