我在写一个解释器,其中Interpreter需要对AST树上的节点做对应的解释,而树上的节点类型为shared_ptr<ASTNode>
,即一个个父类指针,他们将指向子类的具体节点。我现在的做法是写了一个visit函数,大体上如下:
RuntimeResult visit(const shared_ptr<ASTNode>& root, Context& context)
{
if(typeid(*root) == typeid(NumberNode))
{
return visit_NumberNode(std::dynamic_pointer_cast<NumberNode>(root), context);
}
else if(typeid(*root) == typeid(StringNode))
{
return visit_StringNode(std::dynamic_pointer_cast<StringNode>(root), context);
}
else{
return RuntimeResult().failure(RuntimeError("No visit method for current node"));
}
}
即通过typeid去检查这个节点实际指向的对象类型,这显然是很愚蠢的做法,而且每添加一种新的节点,我总需要回来加一条if判断。请问是否有一种办法能够优化这段代码?
我知道python中有如下功能,c++能否也做到?
def visit(self, node, context):
method_name = f'visit_{type(node).__name__}'
method = getattr(self, method_name, self.no_visit_method)
return method(node, context)