再帰を使用してツリーをトラバースしようとしていますが、基本クラスがテンプレート クラスであるため、問題が発生しています。以下にコードを示します。
問題が発生するのは、RootNodetraverse
関数が呼び出されたときに、ノードのすべての子クラスに EmptyVisitor クラスが引き続き使用されるためです。しかし、この問題を克服できるかどうかはわかりません。EmptyVisitor ではなく TransformVisitor を使用していることを「知る」には、TransformNode が必要です。私の言いたいことを説明できれば幸いです。
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` to `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 i = node->getChildren().begin(); i != 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;
}
出力:
Empty Visitor
Empty Visitor
期待される出力:
Empty Visitor
Transform Visitor