Trying to make a templated recursive tree printer
<p>I'm trying to make a recursive tree printer for a template class tree so that it can print the tree without knowing what kind of data is there beforehand.  But I can't figure the syntax out that I need.</p>

<p>Right now I know that the code would only print the root of the tree, but I can't even get it to do that.</p>

<p>Ideas?</p>

<p>edit:</p>

<p>Here's the compiler error messages:</p>

<pre><code>test.cpp(8) : error C2079: 'tempValue' uses undefined class 'Object'
test.cpp(9) : error C2228: left of '.retrieve' must have class/struct/union
        type is 'HWTreeItr&lt;Object&gt; *'
        with
        [
            Object=Object
        ]
        did you intend to use '-&gt;' instead?
test.cpp(27) : error C2664: 'print_tree' : cannot convert parameter 1 from 'HWTreeItr&lt;Object&gt;' to 'HWTreeItr&lt;Object&gt; *'
        with
        [
            Object=char
        ]
        and
        [
            Object=Object
        ]
        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
</code></pre>

<hr>

<p>HWTreeOriginal.h</p>

<pre><code>/*====================================================================

  Tree data structure

  Tree points to a single TreeNode that acts as the root --&gt; no siblings

  TreeNodes points to child TreeNode and to sibling TreeNod

  ====================================================================*/

#ifndef HWTREE_H
#define HWTREE_H

#include &lt;list&gt;

using namespace std;

/* ================================================================

 Class Declarations

/  ================================================================ */

template &lt;class Object&gt;
class HWTree;

template &lt;class Object&gt;
class HWTreeItr;

/* -------------------------------------------------------
 TreeNode -- used internally
   ------------------------------------------------------- */
template &lt;class Object&gt;
class HWTreeNode
{
private:
    HWTreeNode(const Object &amp; element=Object(), HWTreeNode* child=NULL, HWTreeNode* sibling=NULL);
 ~HWTreeNode();

    Object m_element;
 HWTreeNode* m_first_child;
 HWTreeNode* m_next_sibling;

    friend class HWTree&lt;Object&gt;;
    friend class HWTreeItr&lt;Object&gt;;
};

/* -------------------------------------------------------
 Tree - used with TreeItr
   ------------------------------------------------------- */
template &lt;class Object&gt;
class HWTree
{
public:
 // constructors
 HWTree( const Object&amp; initial_element);
 ~HWTree();

 // accessors
    HWTreeItr&lt;Object&gt; get_root();

 //mutators
 void add_child(const Object&amp; obj, const HWTreeItr&lt;Object&gt;&amp; itr);
 void add_sibling(const Object&amp; obj, const HWTreeItr&lt;Object&gt;&amp; itr);
 void remove_left_child(const HWTreeItr&lt;Object&gt;&amp; itr);

private:
 HWTreeNode&lt;Object&gt;* m_root;
};


/* -------------------------------------------------------
 TreeItr class; maintains "current position" in Tree
   ------------------------------------------------------- */
template &lt;class Object&gt;
class HWTreeItr
{
public:
 // constructor
    HWTreeItr( );
 // accessors
    bool retrieve(Object &amp; result) const;
 // mutators
 void next_sibling( );
 void child();
 bool isPastEnd() const;
    friend class HWTreeNode&lt;Object&gt;;

private:
 HWTreeNode&lt;Object&gt;* m_current;
    friend class HWTree&lt;Object&gt;;
};



/* ================================================================

 Tree Node Class Code

/  ================================================================ */
template &lt;class Object&gt;
HWTreeNode&lt;Object&gt;::HWTreeNode(const Object &amp; element=Object(), HWTreeNode* child=NULL, HWTreeNode* sibling=NULL)
: m_element(element), m_first_child(child), m_next_sibling(sibling)
{ }

template &lt;class Object&gt;
HWTreeNode&lt;Object&gt;::~HWTreeNode()
{
 if (m_first_child != NULL)
  delete m_first_child;
 if (m_next_sibling != NULL)
  delete m_next_sibling;
}

/* ================================================================

 Tree Code

   ================================================================ */
template &lt;class Object&gt;
HWTree&lt;Object&gt;::HWTree( const Object&amp; initial_element)
{
    m_root = new HWTreeNode&lt;Object&gt;(initial_element); // create TreeNode
}

template &lt;class Object&gt;
HWTree&lt;Object&gt;::~HWTree()
{
 delete m_root;
}


/* ================================================================

 TreeItr Code

   ================================================================ */
/**
 * Return an iterator representing the first node in the list.
 * This operation is valid for empty lists.
 */
template &lt;class Object&gt;
HWTreeItr&lt;Object&gt; HWTree&lt;Object&gt;::get_root( ) 
{
 HWTreeItr&lt;Object&gt; itr;
 itr.m_current = m_root;
 return itr;
}

template &lt;class Object&gt;
void HWTree&lt;Object&gt;::add_child(const Object&amp; obj, const HWTreeItr&lt;Object&gt;&amp; itr)
{
 if (itr.m_current != NULL)
 {
  HWTreeNode&lt;Object&gt;* pNew = new HWTreeNode&lt;Object&gt;(obj, NULL);  // 1) new node without children
  pNew-&gt;m_next_sibling = itr.m_current-&gt;m_first_child;    // 2) hook into exising children
  itr.m_current-&gt;m_first_child = pNew;
 }
}

template &lt;class Object&gt;
void HWTree&lt;Object&gt;::add_sibling(const Object&amp; obj, const HWTreeItr&lt;Object&gt;&amp; itr)
{
 if (itr.m_current != NULL)
 {
  HWTreeNode&lt;Object&gt;* pNew = new HWTreeNode&lt;Object&gt;(obj, NULL);  // 1) new node without children
  pNew-&gt;m_next_sibling = itr.m_current-&gt;m_next_sibling;    // 2) hook into exising children
  itr.m_current-&gt;m_next_sibling = pNew;
 }
}

template &lt;class Object&gt;
void HWTree&lt;Object&gt;::remove_left_child(const HWTreeItr&lt;Object&gt;&amp; itr)
{
return;
}



/* ================================================================

 Class: Tree Iterator

/  ================================================================ */
template &lt;class Object&gt;
HWTreeItr&lt;Object&gt;::HWTreeItr( ) : m_current( NULL ) 
{}

template &lt;class Object&gt;
bool HWTreeItr&lt;Object&gt;::isPastEnd() const
{
 if (m_current == NULL)
  return true;
 else
  return false;
}

template &lt;class Object&gt;
bool HWTreeItr&lt;Object&gt;::retrieve(Object &amp; result) const
{ 
 if (m_current != NULL)  // bug: _current != ____.end() but where to get a list
 {
  HWTreeNode&lt;Object&gt;* pNode = m_current;
  if (pNode != NULL)  // another attemp to catch crash
   result = pNode-&gt;m_element;
  return true;
 } else
  return false;
}

template &lt;class Object&gt;
void HWTreeItr&lt;Object&gt;::next_sibling( )
{ 
 if (m_current != NULL)
  m_current = m_current-&gt;m_next_sibling;
}


template &lt;class Object&gt;
void HWTreeItr&lt;Object&gt;::child()
{ 
 if (m_current != NULL)
  m_current = m_current-&gt;m_first_child;
}



#endif
</code></pre>

<hr>

<p>test.cpp</p>

<pre><code>#include "HWTreeOriginal.h"
#include &lt;iostream&gt;
#include &lt;string&gt;
using namespace std;

void print_tree(HWTreeItr&lt;class Object&gt;* currentItr, int level=0)
{
    Object tempValue;
    currentItr.retrieve(tempValue);
    cout &lt;&lt; string( level, ' ' ) &lt;&lt; tempValue;
}

int main()
{
    HWTree&lt;char&gt; myTree('A');
    HWTreeItr&lt;char&gt; myItr = myTree.get_root();
    HWTreeItr&lt;char&gt; tempItr;

    myTree.add_child('B', myItr);
    myItr.child();
    tempItr=myItr;
    myTree.add_sibling('C', myItr);
    myItr.next_sibling();
    myTree.add_sibling('D', myItr);

    myItr=myTree.get_root();
    print_tree((HWTreeItr&lt;char&gt;)myItr, 0);
    return 0;
}
</code></pre>
