我得到了一个类似“树”的结构,它表示一个简单的加法表达式。(例如2 + 4 +(3 + 5))
我使用访问者模式遍历树并找到总和。问题是我希望我的实现使用模板,这会导致一些奇怪的错误。
我需要每个子表达式的accept函数能够返回任何类型,这样我就可以执行不仅仅是整数操作
#include <iostream>
#include <vector>
#define print(x) std::cout << x << "\n";
class Add;
class Number;
// Basic template for visitor class
template <class T>
class Visitor {
public:
virtual T visitAdd(Add* add) = 0;
virtual T visitNumber(Number* num) = 0;
};
// Visitor made for adding
template <class T>
class Adder : public Visitor<T> {
public:
T visitAdd(Add* add) override;
T visitNumber(Number* num) override;
};
// Node types for expression tree
class Expr {
public:
template <class T>
virtual T accept(Visitor<T>* visitor) = 0;
};
class Add : public Expr {
public:
Expr* left;
Expr* right;
Add(Expr* left, Expr* right) : left(left), right(right) {};
template <class T>
T accept(Visitor<T>* visitor) {
return visitor->visitAdd(this);
}
};
class Number : public Expr {
public:
int value;
Number(int value) : value(value) {};
template <class T>
T accept(Visitor<T>* visitor) {
return visitor->visitNumber(this);
}
};
template <class T>
T Adder<T>::visitAdd(Add* add) {
return add->left->accept(this) + add->right->accept(this);
}
template <class T>
T Adder<T>::visitNumber(Number* num) {
return num->value;
}
int main() {
// Should represent (5 + 2) + (7 + (4 + 2))
Expr* expression = new Add(
new Add(
new Number(5),
new Number(2)
),
new Add(
new Number(7),
new Add(
new Number(4),
new Number(2)
)
)
);
// Print sum as int
Adder<int> intAdder = Adder<int>();
print(expression->accept(&intAdder));
// Print sum as float
Adder<float> floatAdder = Adder<float>();
print(expression->accept(&floatAdder));
return 0;
}
字符串
错误:函数模板声明中不允许“virtual”(对于Expr::accept)
1条答案
按热度按时间368yc8dk1#
解决这个问题的一种方法是删除返回值并将结果保留在访问者内部。这样
Visitor<T>
就变成字符串
Adder
也将删除返回值,并添加结果字段型
并且
Expr::accept
也将丢弃其模板参数。在main
中,您必须从Adder<int>
示例中提取结果。