You created a dynamic container - eg. the one, which is built during the runtime. In case of such structures, you have to allocate them dynamically and use pointer to refer to them. That is:
MyBinaryTree * BuildSimpleTree()
{
BinaryTree<int> * node1 = new BinaryTree(0, nullptr, nullptr);
BinaryTree<int> * node2 = new BinaryTree(0, nullptr, nullptr);
return new MyBinaryTree<int>(0, node1, node 2);
}
MyBinaryTree * tree = BuildSimpleTree();
The reason behind dynamic allocation requirement is that all local statically allocated objects (eg. residing on stack instead of heap) are automatically destroyed, when you leave the function or method. However, for the tree to work properly, all its children (and recursively their children) shall remain alive after returning from function, so they have to be allocated dynamically.
You have to remember though to free all instances of allocated classes. This may be done manually or automatically, recursively - in BinaryTree and MyBinaryTree dtors.
If you are able to compile your code using C++11, there's always an option to use move semantics - you'll be able to return the tree by value and keep the code fast and memory-efficient at the same time. This solution would look like the following:
template <class T>
struct MyBinaryTree
{
T val;
BinaryTree<T>* left;
BinaryTree<T>* right;
BinaryTree<T>(T v, BinaryTree<T>* l, BinaryTree<T>* r)
: val(v), left(l), right(r)
{
}
BinaryTree<T>(BinaryTree<T> && r)
{
val = r.val;
left = r.left;
right = r.right;
}
};
Then, you can return your tree by value (but still building nodes dynamically):
MyBinaryTree BuildTree()
{
auto left = new BinaryTree<int>(0, nullptr, nullptr);
auto right = new BinaryTree<int>(0, nullptr, nullptr);
MyBinaryTree<int> result(0, left, right);
return result;
}