动态访问联合

accessing unions dynamically

我有这个枚举、联合和结构:

union num {
    int i;
    short s;
    float f;
    double d;
};
enum tag {SHORT, INT, FLOAT, DOUBLE};
struct vrnumber {
    num num;
    tag type;
};

我想知道如何根据另一个变量(即用户的输入)动态访问联合内的变量。 (即)我想对联合的变量进行某种操作但我想知道在运行时要访问哪个联合变量。那么什么是更好的方法而不是像这样的方法:

vrnumber m; 
switch (m.type) {
    case SHORT: //an operation ..
    case INT: //same operation ...
    case FLOAT: //same operation ...
    case DOUBLE: //same operation ...
}

我认为这是非常冗长和多余的,而在每种情况下它都是相同的操作,唯一的区别是当我访问联合来存储或使用该值时。

一种方法是在结构定义中定义将要使用的运算符。例如,如果要使用运算符 -,请定义这些方法:

struct vrnumber {
    num num;
    tag type;

    //between vrnumbers
    vrnumber operator- (const vrnumber& rhs);

    //vrnumbers and basic types
    vrnumber operator- (const int& rhs);
    vrnumber operator- (const double& rhs);

    //if vrnumber is used as rhs
    friend vrnumber operator- (const int& lhs, const vrnumber& rhs);
    friend vrnumber operator- (const double& lhs, const vrnumber& rhs);
};

这些是其中一些方法的定义示例:

vrnumber vrnumber::operator- (const vrnumber& rhs){
    switch(type){
        case SHORT:
            switch(rhs.type){
                //......
                //cases here
        }
        //......
        //cases here
    }
}
vrnumber vrnumber::operator- (const int& rhs){
    switch(type){
        case SHORT: return num.s-rhs;
        case INT: return num.i-rhs;
        case FLOAT: return num.f-rhs;
        case DOUBLE: return num.d-rhs;          
    }
}
vrnumber operator- (const int& lhs, const int& rhs){
    switch(rhs.type){
        //..........
        //...cases, same as the others
    }
}

以下是使用这些操作的一些示例:

vrnumber m1;
vrnumber m2;
int i1;
float f1;
//the example:
m1=f1-(m1-m2)-i1;

使用这种方法的代价是冗长的运算符定义。但是,如果这种操作在代码中被调用 很多次,那么这可能会缩短和简化代码。