我想为一个解释进行递归评估的树,该解释根据几行中的评估返回不同的类型,并且没有void *
,所以这是我尝试做和做的代码的一个小例子不行
#include <iostream>
using namespace std;
struct node{
node(string _text){
child = NULL;
sibling = NULL;
text = _text;
}
node *child;
node *sibling;
string text;
};
auto evaluate(node *n){
if(n->text == "sum"){
return (int)evaluate(n->child) + (int)evaluate(n->child->sibling);
}else if(n->text == "lt"){
return (int)evaluate(n->child) < (int)evaluate(n->child->sibling);
}else{
return atoi(n->text.c_str());
}
}
int main(){
node sum = node("sum");
node a_value = node("23");
node b_value = node("13");
sum.child = &a_value;
sum.child->sibling = &b_value;
cout << (int)evaluate(&sum) << endl;
}
我想知道是否有使用现代c ++的简单方法。
答案 0 :(得分:1)
evaluate()有3种情况,其中2种情况返回int值,一种情况返回bool。布尔型可以隐式转换为int,因此,如果validate()的返回类型始终为int,则适用于所有情况:
int evaluate(const node* n)
{
if (n->text == "sum") {
return evaluate(n->child) + evaluate(n->child->sibling);
}
if (n->text == "lt") {
return evaluate(n->child) < evaluate(n->child->sibling);
}
return atoi(n->text.c_str());
}
答案 1 :(得分:1)
在C ++中,auto
在编译时确定。因此,它永远不会是运行时变化的解决方案。另一种构造类型可以是模板,但是它们的类型推导机制也是编译时。
您需要的是运行时类型确定。这里有几个简单的解决方案:
Value
类,该类允许组合不同基本类型的值。多态可以帮助您以优雅且可扩展的方式实现这种类型。 std::variant<...>
,例如std::variant<int, double, string>
。变量的值可以是列表中的任何预定义类型。这是一种类型安全的联合。不便之处在于,您的评估逻辑将需要检查变量的类型以调用正确的操作(因为操作与类型相关,并且必须在编译时知道)。 std::any
。这与变体非常相似。它只是更加灵活,因为您不需要预先定义允许的类型。但是从技术上讲,对于您的评估逻辑,您仍然知道可以为所有可能的类型和组合调用正确的操作的可能类型。 无论您选择什么,并且与您的主要问题没有直接关系,您都可能会感兴趣:
evaluate()
中添加一个附加参数以引用评估上下文(例如,符号表,如果您的表达式也可以包含变量)。 node
和evaluate()
。