title: C++ Boost recursive variant overloading apply_visitor
body: <p>abstract: I am looking to overload the apply_visitor() method in a class that contains a recursive boost::variant object.</p>
  
  <p>In the code included below there is the method:</p>
  
  <pre><code>template &lt;typename T&gt;
  ostream&amp; apply_visitor(const T&amp; fn) const
  </code></pre>
  
  <p>I would like to overload this method for different visitors. Something like this:</p>
  
  <pre><code>ostream&amp; apply_visitor(const PrintData&amp; fn) const
  </code></pre>
  
  <p>But the problem is that the class PrintData is not yet complete (see comments in the code below). It is defined after the Node class. So I have two questions (among others -- I would welcome a general critique on this code which is modeling something I'd like to put into production).</p>
  
  <p>1) Is there a way to get apply_visitor(PrintData&amp;) to work?</p>
  
  <p>2) Can I rearrange the (recursive) variant so all visitor methods are in PrintData and I wouldn't have to add apply_visitor to the Node class?</p>
  
  <pre class="lang-cpp prettyprint-override"><code>/**
   * compiled with gcc (tested with 4.7.2 on linux)
   * requires the boost development headers to be discoverable
   * by the compiler.
   *
   * g++ -otest-recursive-visit -std=c++11 test-recursive-visit.cpp
   * ./test-recursive-visit
   **/
  
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  #include "boost/variant.hpp"
  #include "boost/variant/recursive_wrapper.hpp"
  #include "boost/variant/static_visitor.hpp"
  
  using namespace std;
  
  /// type name demangler (as implemented in g++). For other compilers,
  /// we could add more #elif statements, but for now, just return
  /// the mangled name.
  #ifdef __GNUG__ /// compiler is g++
  #include &lt;cxxabi.h&gt;
  string type_demangle(const string&amp; name)
  {
      int status;
      char* res = abi::__cxa_demangle(
          name.c_str(), NULL, NULL, &amp;status);
      string demangled_name((status==0) ? res : name);
      free(res);
      return demangled_name;
  }
  #else /// compiler is not g++
  string type_demangle(const string&amp; name) { return name; }
  #endif
  
  /// forward declaration of the Node class
  /// (needed for recursive variant type)
  class Node;
  
  /// the actual recursive variant type
  /// (typically hidden from the users)
  typedef boost::variant&lt;
      boost::recursive_wrapper&lt;Node&gt;,
      vector&lt;int&gt;,
      vector&lt;float&gt;
  &gt; data_t;
  
  // forward declaration for PrintData. See note below concerning
  // Node::apply_visitor()
  class PrintData;
  
  /// this is the object users will see
  /// for prototyping, the tree object is public
  class Node
  {
    public:
      /// sub-nodes are identified by unique strings
      /// which point to one of the objects that data_t
      /// can hold
      map&lt;string,data_t&gt; tree;
  
      /// constructor for a std::map object, passed to tree
      Node(const initializer_list&lt;pair&lt;const string,data_t&gt;&gt;&amp; l)
      : tree(l)
      {}
  
      //
      // INTERESTING PART OF THIS EXAMPLE IS HERE
      //
      // I tried to replace T&amp; with PrintData&amp; adding
      // a forward declaration at the top but I get the
      // errors:
      //
      //  line 86:
      //      invalid use of incomplete type ‘const class PrintData’
      //  line 53:
      //      forward declaration of ‘const class PrintData’
      //
  
      /// This is called by boost::apply_visitor(Visitor(),Node)
      //ostream&amp; apply_visitor(const PrintData&amp; fn) const
      template &lt;typename T&gt;
      ostream&amp; apply_visitor(const T&amp; fn) const
      {
          for (auto i : tree)
          {
              *fn.os &lt;&lt; fn.prefix &lt;&lt; i.first;
              i.second.apply_visitor(fn);
          }
          return *fn.os;
      }
  };
  
  /// the printing visitor to ostream object
  class PrintData : public boost::static_visitor&lt;ostream&amp;&gt;
  {
    public:
      ostream* os;
      string prefix;
  
      /// keep a pointer to the ostream and keep
      /// a prefix string which will hold and "indent"
      /// which is something like "  " for every level
      /// of recursion
      PrintData(ostream&amp; out_stream, const string&amp; prefix_str="")
      : os(&amp;out_stream)
      , prefix(prefix_str)
      {}
  
      /// recurse into the tree, adding indent characters to prefix
      ostream&amp; operator()(Node&amp; n) const
      {
          *os &lt;&lt; endl;
          n.apply_visitor(PrintData(*os, prefix+"  "));
          *os;
      }
  
      /// actual data types that we want to print out
      template &lt;typename T&gt;
      ostream&amp; operator()(const vector&lt;T&gt;&amp; d) const
      {
          *os &lt;&lt; " (vector&lt;" &lt;&lt; type_demangle(typeid(T).name()) &lt;&lt; "&gt;):";
          for (T i : d)
          {
              *os &lt;&lt; " " &lt;&lt; i;
          }
          *os &lt;&lt; endl;
          return *os;
      }
  };
  
  /// convenience operator to allow: cout &lt;&lt; node;
  ostream&amp; operator&lt;&lt;(ostream&amp; os, const Node&amp; n)
  {
      return boost::apply_visitor(PrintData(os), n);
  }
  
  
  int main()
  {
      /// hooray for initialization lists!!!
      Node n {
          {"X", Node{
              {"a", vector&lt;int&gt;{1,2,3}},
              {"b", vector&lt;float&gt;{2,3,4}}
          }},
          {"Y", vector&lt;int&gt;{3,4,5}},
          {"Z", Node{
              {"A", Node{
                  {"c", vector&lt;float&gt;{4,5,6}}
              }}
          }}
      };
  
      /**
      applying PrintData to n prints out the following:
  
      X
        a (vector&lt;int&gt;): 1 2 3
        b (vector&lt;float&gt;): 2 3 4
      Y (vector&lt;int&gt;): 3 4 5
      Z
        A
          c (vector&lt;float&gt;): 4 5 6
  
      **/
      cout &lt;&lt; n;
  }
  </code></pre>