recursion - C++ Boost recursive variant overloading apply_visitor -


abstract: looking overload apply_visitor() method in class contains recursive boost::variant object.

in code included below there method:

template <typename t> ostream& apply_visitor(const t& fn) const 

i overload method different visitors. this:

ostream& apply_visitor(const printdata& fn) const 

but problem class printdata not yet complete (see comments in code below). defined after node class. have 2 questions (among others -- welcome general critique on code modeling i'd put production).

1) there way apply_visitor(printdata&) work?

2) can rearrange (recursive) variant visitor methods in printdata , wouldn't have add apply_visitor node class?

/**  * compiled gcc (tested 4.7.2 on linux)  * requires boost development headers discoverable  * compiler.  *  * g++ -otest-recursive-visit -std=c++11 test-recursive-visit.cpp  * ./test-recursive-visit  **/  #include <iostream> #include <map> #include <string> #include <vector>  #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++). other compilers, /// add more #elif statements, now, return /// mangled name. #ifdef __gnug__ /// compiler g++ #include <cxxabi.h> string type_demangle(const string& name) {     int status;     char* res = abi::__cxa_demangle(         name.c_str(), null, null, &status);     string demangled_name((status==0) ? res : name);     free(res);     return demangled_name; } #else /// compiler not g++ string type_demangle(const string& name) { return name; } #endif  /// forward declaration of node class /// (needed recursive variant type) class node;  /// actual recursive variant type /// (typically hidden users) typedef boost::variant<     boost::recursive_wrapper<node>,     vector<int>,     vector<float> > data_t;  // forward declaration printdata. see note below concerning // node::apply_visitor() class printdata;  /// object users see /// prototyping, tree object public class node {   public:     /// sub-nodes identified unique strings     /// point 1 of objects data_t     /// can hold     map<string,data_t> tree;      /// constructor std::map object, passed tree     node(const initializer_list<pair<const string,data_t>>& l)     : tree(l)     {}      //     // interesting part of example here     //     // tried replace t& printdata& adding     // forward declaration @ top     // errors:     //     //  line 86:     //      invalid use of incomplete type ‘const class printdata’     //  line 53:     //      forward declaration of ‘const class printdata’     //      /// called boost::apply_visitor(visitor(),node)     //ostream& apply_visitor(const printdata& fn) const     template <typename t>     ostream& apply_visitor(const t& fn) const     {         (auto : tree)         {             *fn.os << fn.prefix << i.first;             i.second.apply_visitor(fn);         }         return *fn.os;     } };  /// printing visitor ostream object class printdata : public boost::static_visitor<ostream&> {   public:     ostream* os;     string prefix;      /// keep pointer ostream , keep     /// prefix string hold , "indent"     /// "  " every level     /// of recursion     printdata(ostream& out_stream, const string& prefix_str="")     : os(&out_stream)     , prefix(prefix_str)     {}      /// recurse tree, adding indent characters prefix     ostream& operator()(node& n) const     {         *os << endl;         n.apply_visitor(printdata(*os, prefix+"  "));         *os;     }      /// actual data types want print out     template <typename t>     ostream& operator()(const vector<t>& d) const     {         *os << " (vector<" << type_demangle(typeid(t).name()) << ">):";         (t : d)         {             *os << " " << i;         }         *os << endl;         return *os;     } };  /// convenience operator allow: cout << node; ostream& operator<<(ostream& os, const node& n) {     return boost::apply_visitor(printdata(os), n); }   int main() {     /// hooray initialization lists!!!     node n {         {"x", node{             {"a", vector<int>{1,2,3}},             {"b", vector<float>{2,3,4}}         }},         {"y", vector<int>{3,4,5}},         {"z", node{             {"a", node{                 {"c", vector<float>{4,5,6}}             }}         }}     };      /**     applying printdata n prints out following:      x       (vector<int>): 1 2 3       b (vector<float>): 2 3 4     y (vector<int>): 3 4 5     z               c (vector<float>): 4 5 6      **/     cout << n; } 

declare function, don't define inside class. instead, wait define until after you've defined printdata, @ point complete type.

class printdata;  class node {   public:   ...     ostream& apply_visitor(const printdata& fn) const;   ... };  class printdata : public boost::static_visitor<ostream&> { ... };  inline ostream& node::apply_visitor(const printdata& fn) const {   ... } 

Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

Swift game error message -