使用 CRTP 将 Base Class 的子 Classes 传递给构造函数?

Passing Child Classes of a Base Class to a constructor using CRTP?

我有以下基础Class:

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 的 Classes:

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 设为模板而不是硬编码它的左右参数必须是文字,它就会起作用:

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