I'm trying to replace the use of raw pointers with smart pointers in my C++ code. The following bit is from my first attempt at a self-balancing binary tree, though there is nothing self-balancing at the moment. I am worried about some fundamental problems regarding the use of unique pointers. template <typename K, typename D> class rbtree { struct rbnode; typedef std::unique_ptr<rbnode> node_ptr; node_ptr root_; struct rbnode { node_ptr left, right; rbnode *parent; enum { Red, Black } color; D data; K key; rbnode(): left(nullptr), right(nullptr), parent(nullptr), color(Red), data(0), key(0) {} rbnode(K k, D d): left(nullptr), right(nullptr), parent(nullptr), color(Red), data(d), key(k) {} rbnode(K k, D d, rbnode *p): left(nullptr), right(nullptr), parent(p), color(Red), data(d), key(k) {} }; node_ptr insert_(node_ptr& node, node_ptr& parent, K& key, D& data); public: bool insert(K& key, D& data); void dfs(std::function<void (K& key, D& data)> visitor); }; template <typename K, typename D> void rbtree<K, D>::dfs(std::function<void (K& key, D& data)> visitor) { } template <typename K, typename D> typename rbtree<K, D>::node_ptr rbtree<K, D>::insert_( node_ptr& node, node_ptr& parent, K& key, D& data) { if (node == 0) { node = node_ptr(new rbnode(key, data, parent.get())); } if (key == node->key) { throw "Key exists!"; } if (key < node->key) { node->left = std::move(insert_(node->left, node, key, data)); } else { node->right = std::move(insert_(node->right, node, key, data)); } return std::move(node); } template <typename K, typename D> bool rbtree<K, D>::insert(K& key, D& data) { root_ = std::move(insert_(root_, root_, key, data)); root_->color = rbnode::Black; return true; }