使用CRTP将基类的子类传递给构造函数



我有以下基类:

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>等等

最新更新