我有以下基类:
class BaseVisitor
{
public:
virtual ~BaseVisitor() {};
};
template <class T>
class Visitor
{
public:
virtual void visit(T&) = 0;
};
template <class Visitable>
class Expression
{
public:
template <typename T>
void accept(T& visitor)
{
visitor.visit(static_cast<Visitable&>(*this));
}
void print() {
static_cast<Visitable*>(this)->print();
}
void eval() {
static_cast<Visitable*>(this)->eval();
}
};
以及从Expression继承的类:
class Literal : public Expression<Literal>
{
protected:
int value = 0;
public:
Literal() {};
Literal(int x);
std::string print();
int eval();
};
class Add : public Expression<Add>
{
protected:
Literal lhs;
Literal rhs;
public:
Add(Literal left, Literal right);
void print();
int eval();
};
我希望能够将表达式传递给Add构造函数,这样我就可以调用Add(Add(Literal(10),Literal(20)),Literal(30)).eval()
,得到50。这在C++11中可能吗?
如果将Add
作为模板而不是硬编码,则其左右参数必须为Literals:
template<typename L, typename R>
class Add : public Expression<Add<L,R>>
{
protected:
L lhs;
R rhs;
public:
Add(L left, R right) : lhs(left), rhs(right) {}
int eval() { return lhs.eval() + rhs.eval(); }
};
编译Add(Add(Literal(10),Literal(20)),Literal(30)).eval()
需要C++17。如果你想让它与C++11一起工作,你需要编写一个类似于std::make_pair
的包装函数,以避免不得不编写Add<Literal, Literal>
等等