通过模板类的派生类的函数递归

时间:2013-10-07 10:38:16

标签: c++ templates recursion

我试图使用递归遍历树,但我遇到了一个问题,因为基类是一个模板类。以下是代码:

出现问题是因为当调用RootNode traverse函数时,它仍然对节点的所有子类使用EmptyVisitor类。但我不知道它是否有可能克服这个问题。我需要TransformNode“知道”它使用TransformVisitor而不是EmptyVisitor。我希望我能解释一下我的意思。

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

1 个答案:

答案 0 :(得分:1)

RootNode类无法知道其他类派生自同一基类的内容。你的设计看起来有点过于模糊,与Visitor模式无关。为什么不使用普通的多态?

这只是一个草图,因为使用多态性会使您的大多数模板工作过时,因此应该进一步重构。但是,这个简单的修复方法将引导您获得所需的结果:

template<class Visitor>
class Node : public BaseNode {
public:

    void traverse() {
        traverse(this);
    }

    void traverse(Node * node) {
        visit();

        for(ChildSet::iterator i = node->getChildren().begin();
            i != 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);
    }
};

也许您对thisthis等内容感兴趣?