# Recursive data-types, binary tree, list-initialization

I have copied the techniques used by https://github.com/nlohmann/json to define a class BSTNode<T> which represents binary search trees and is possible to initialise as follows. Each triple {x, y, z} denotes a node whose value is x, whose left sub-tree is y and whose right sub-tree is z.

#include <cstddef>

using namespace std;

BSTNode<int> tree = {
19,
{
7,
{3, 2, 5},
{
11,
nullptr,
{17, 13, nullptr}
}
},
{
43,
{
23,
nullptr,
{
37,
{29, nullptr, 31},
41
}
},
{47, nullptr, 53}
}
};


The code for BSTNode<T> is as follows:

#include <cstddef>
#include <initializer_list>
#include <memory>

template <typename T>
class BSTNode {
private:
using node_ptr = std::unique_ptr<BSTNode<T>>;

public:
T data;
node_ptr left;
node_ptr right;

private:
struct BSTNode_reference {
node_ptr reference;

BSTNode_reference (std::nullptr_t null) {}

BSTNode_reference (T&& data) :
reference(std::make_unique<BSTNode<T>>(BSTNode(std::forward<T>(data)))) {}

BSTNode_reference (node_ptr&& node_pointer) :
reference(std::forward(node_pointer)) {}

BSTNode_reference (T&& data, BSTNode_reference&& left, BSTNode_reference&& right) :
reference(std::make_unique<BSTNode<T>>(BSTNode(std::forward<T>(data),
std::forward<BSTNode_reference>(left),
std::forward<BSTNode_reference>(right)))) {}
};

public:
BSTNode (T&& data) : data(std::forward<T>(data)) {}

BSTNode (T&& data, BSTNode_reference&& left, BSTNode_reference&& right) :
data(data),
left(std::forward<node_ptr>(left.reference)),
right(std::forward<node_ptr>(right.reference)) {}
};


You might ask why I would want to be able to define trees in such a way. It helps immensely for writing tests for the algorithms which I define over trees, and I would like to apply this method to other recursive data-types.

I feel that my solution is quite cumbersome in comparison to the simplicity of its intent. Can this be done in a more idiomatic way or cleaned up at all?