关于模板和虚拟类运行时类型的问题

Question about template and virtual class runtime type

提问人:Junhui Zhu 提问时间:8/13/2023 更新时间:8/13/2023 访问量:58

问:

我正在用 C++ 编写解释器并遇到了一些语言问题。

我有一个类叫 ,这是一个纯虚拟类。ValuableAST

class ValuableAST
{
public:
    virtual ~ValuableAST() = default;
    virtual bool is_checked() const
    {
        return false;
    }

    enum class ValueType
    {
        INTEGER,
        REAL
    };

    virtual std::variant<int, double> value() const = 0;
};

这里总是 false,因为我将对类型为 的所有节点进行语义类型检查。is_checkedValuableAST

例如,我有一个类:Number

class Number : public ValuableAST
{
private:
    std::variant<int, double> value_;

public:
    std::variant<int, double> value() const
    {
        return value_;
    }

    explicit Number(int value) : value_(value) {}

    explicit Number(double value) : value_(value) {}

    explicit Number(Number *number) : value_(number->value()) {}
};

然后,我想包装类,就像在运行时进行类型检查之后一样。所以我使用模板来做到这一点:Number

template <class T>
    requires std::is_base_of_v<ValuableAST, T>
class TypeChecked
    : public T
{
private:
    ValuableAST::ValueType type_;

public:
    explicit TypeChecked(ValuableAST::ValueType type, T *value)
        : T(value), type_(type) {}

    ValuableAST::ValueType type() const { return type_; }

    bool is_checked() const override { return true; }

    int get_int() const
    {
        if (type_ == ValuableAST::ValueType::INTEGER)
        {
            return std::get<int>(this->value());
        }
        else
        {
            throw std::runtime_error("Type error");
        }
    }

    double get_real() const
    {
        if (type_ == ValuableAST::ValueType::REAL)
        {
            return std::get<double>(this->value());
        }
        else
        {
            throw std::runtime_error("Type error");
        }
    }
};

现在我有一个函数,它接受指向 的指针的参数。我想在这个函数中实现它,我可以根据参数指向的对象的实际类型生成对象:function_accepting_valuable_astValuableASTTypeChecked

void function_accepting_valuable_ast(ValuableAST *ast)
{
    // generate the type-checked AST object of the given AST object
    // If ast is a Number object, then the generate object is a TypeChecked<Number> object.
    // If ast is another object like a UnaryOperation, I need a TypeChecked<UnaryOperation> object

    const auto type_checked_ast = ...;
}

但是,这里我们不知道真正的类型,我无法生成相应的对象,我被困在这里,想为这种情况寻求更好的实践。ast

C++ 模板 虚拟函数

评论

0赞 Ted Lyngmo 8/14/2023
type_checked_ast必须是一个,因为这里有运行时多态性。std::variant<TypeChecked<Number>, TypeChecked<UnaryOperation>>
2赞 Jarod42 8/14/2023
enum class ValueType不需要,知道它的类型。std::variant
0赞 Pete Becker 8/14/2023
回复:“这是一个纯虚类”——任何至少有一个纯虚函数的类都是一个抽象类
0赞 T W Bennet 8/14/2023
将function_accepting_valuable_ast放入类 TypeChecked 中是否有意义,可能是作为虚拟函数。?然后它的身体就可以接触到T。

答: 暂无答案