在 C++ 中创建动态数据类型

Creating dynamic data-type in C++

我正在用 C++ 创建特定语言的解释器。在创建解析器、实现范围解析等之后,我遇到的唯一问题是实现动态类型变量。

根据一些分散的一般性建议,我创建了 VarData 和 VarType 结构:

union VarData{
    int IntData;
    char CharData;
    double DoubleData;
};

enum class VarType {
    Int,
    Char,
    Double
};

和一个可变结构体(显然是不完整的):

struct Variable {

VarData data;

VarType type;

template<typename T>
void operator =(T val) {

    std::string name = typeid(T).name();

    if (name == "char") {
        data.CharData = val;
        type = VarType::Char;
    }
    else if (name == "int") {
        data.IntData = val;
        type = VarType::Int;
    }
    else if (name == "double") {
        data.DoubleData = val;
        type = VarType::Double;
    }

}
};

这确实有效,例如在此示例代码中,所有分配的值都已正确存储:

int main() {

Variable a;

a = '5';  // a.type is now VarType::Char
a = 57;   // a.type is now VarType::Int
a = 8.032;   // a.type is now VarType::Double

}

我遇到的问题是,如果我想使用 Variable 结构,我需要为所有常见运算符(+、-、/、* 等)重载运算符,每个运算符都需要涵盖所有可能的成对变量可以采用的类型。例如,

Variable operator + (Variable& v1, Variable& v2) {

    if (v1.type == VarType::Char && v2.type == VarType::Char)
        //return Variable of type int
    else if (v1.type == VarType::Double && v2.type == VarType::Int)
        // return Variable of type double
    else if (...)
}

是否有任何其他(不涉及数百万嵌套 if 语句)方法来做到这一点?

抱歉,如果我的问题不是很清楚,我很乐意提供额外的解释。

处理所有可能的不同类型组合的一种方法是使用 double dispatch 根据涉及的类型执行操作。

双重分派将简化对要执行的操作变体的确定。这意味着很多(如果更少的话),将重载覆盖或调度 table 机械地找到 suitable 操作的职责留给一些巧妙的组合。不过,也算不上组合爆的真正掌握。

另一种更有效的方法是应用一些系统类型的提升规则。例如,如果你想在一个操作中组合一个整数和一个浮点数,你会在执行操作之前将所有内容都转换为浮点数。

如果在为相同类型的两个值调用 suitable 运算符重载之前使用 interpreter pattern, you could have a template method pattern 管理类型提升。

无关但重要: 您需要注意 typeid() 不是标准值。所以 "int"、"double" 等...是一个很好的实现,但其他字符串可能会用于其他编译器。这使您的代码非 portable