c++ - recursion through a function of derived classes of a template class -
i trying traverse through tree using recursion encountering problem because base class template class. here code below:
the problem arises because when rootnode traverse
function called still uses emptyvisitor class child classes of node. not know if possible overcome issue. need transformnode "know" using transformvisitor not emptyvisitor. hope explain mean.
class basenode { public: typedef std::set<basenode *> childset; protected: childset mchildren; basenode * mparent; public: basenode(basenode * parent=0) : mparent(parent) {} ~basenode() {} basenode * addchild(basenode * node); //adds `node` `mchildren` inline basenode * getparent() { return mparent; } inline const childset &getchildren() const { return mchildren; } inline childset &getchildren() { return mchildren; } };
class emptyvisitor { public: static void visit(basenode * node) {std::cout << "empty visitor\n";} }; class transformvisitor { static void visit(basenode * node) { std::cout << "transform visitor\n"; } }; template<class visitor> class node : public basenode { public: void traverse() { traverse(this); } void traverse(node * node) { visitor::visit(this); for(childset::iterator = node->getchildren().begin(); != node->getchildren().end(); ++i) { traverse(static_cast<node*>((*i))); } } };
class rootnode : public node<emptyvisitor> { }; class transformnode : public node<transformvisitor> { };
main.cpp
int main() { rootnode * root = new rootnode; root->addchild(new transformnode); root->traverse(); return 0; }
output:
empty visitor empty visitor
expected output:
empty visitor transform visitor
there no way rootnode
class know other classes derive same base class. design seems bit obfuscated, , has nothing visitor pattern. why not use ordinary polymorphism?
this sketch, using polymorphism makes of template work obsolete, should further refactored. simple fix, lead desired result:
template<class visitor> class node : public basenode { public: void traverse() { traverse(this); } void traverse(node * node) { visit(); for(childset::iterator = node->getchildren().begin(); != node->getchildren().end(); ++i) { traverse(static_cast<node*>((*i))); } } virtual void visit() { visitor::visit(this); } }; class transformnode : public node<transformvisitor> { void visit() { transformvisitor::visit(this); } };
Comments
Post a Comment