C++ C++;开关中变量类型的确定 编辑:感谢您的回复。在开关上增加断路器;问题确实是,我希望能够在switch语句之后使用struct。

C++ C++;开关中变量类型的确定 编辑:感谢您的回复。在开关上增加断路器;问题确实是,我希望能够在switch语句之后使用struct。,c++,struct,C++,Struct,我希望能够做到以下几点: int foo (int type, void* inVar) { switch(type) { case 0: struct struct-type-one mystruct = *( (struct struct-type-one*) inVar); break; case 1: struct struct-type-two mystruct = *( (struct struct-ty

我希望能够做到以下几点:

int foo (int type, void* inVar) {    
    switch(type) {
    case 0:
        struct struct-type-one mystruct = *( (struct struct-type-one*) inVar);
        break;
    case 1:
        struct struct-type-two mystruct = *( (struct struct-type-two*) inVar);
        break;
    case 2:
        struct struct-type-three mystruct = *( (struct struct-type-three*) inVar);
        break;
    }
    // use mystruct.data
}
基本上,
inVar
是指向结构的指针,
type
告诉我们需要什么类型。结构都有数据,但结构的类型决定了数据的类型。我想这样做是因为在切换后的代码中,我们可以对
mystruct.data
执行操作,而不必担心数据的实际类型

我的问题是,我们如何才能做到这一点?例如,在Python中这将是很容易的,但是C++不喜欢<代码> MyStult是“交叉初始化”,即可以根据开关语句的哪个分支使用不同的类型。模板化是我们一直在努力解决的一个想法,但这很困难,因为结构的名称不同,例如
struct intStruct
struct floatStruct
。这很重要,因为这些结构的大小取决于数据类型。有什么想法吗?

你就快到了:

int foo (int type, void* inVar) {    
    switch(type) {
    case 0: {
        struct_type_1& mystruct = *static_cast<struct_type_1*>(inVar);
        // use mystruct here
    }
    break;
    case 1: {
        // same thing again
    }
    }
}
intfoo(int类型,void*inVar){
开关(类型){
案例0:{
结构类型1和mystruct=*静态类型转换(因瓦);
//在这里使用mystruct
}
打破
案例1:{
//同样的事情
}
}
}
您最大的问题可能是没有在每个箱体周围使用支架。这意味着您的
mystruct
变量发生冲突


要了解更多关于这类事情的信息,您可能需要查找的一个关键短语是“歧视性联盟”。另外,请查看Boost Variant以了解处理它的另一种方法。

您可以使用类似以下内容:

int bar(Data& data);

int foo (int type, void* inVar) {    
    switch(type) {
        case 0: return bar(static_cast<struct_type_0*>(inVar)->data);
        case 1: return bar(static_cast<struct_type_1*>(inVar)->data);
        case 2: return bar(static_cast<struct_type_2*>(inVar)->data);
    }
    return -1;
}
int-bar(数据和数据);
int foo(int类型,void*inVar){
开关(类型){
案例0:返回条(静态铸造(因瓦)->数据);
案例1:返回条(静态铸造(因瓦)->数据);
案例2:返回条(静态铸造(因瓦)->数据);
}
返回-1;
}

我不相信直接做你想做的事情是可能的(即使是这样,这也是C/C++中的一种反模式)。但是,如果您想使用
mystruct.data
(而不是
mystruct
本身),则可以通过以下方式重写代码:

int foo (int type, void* inVar) {    
    void* mystruct_data = NULL;

    switch(type) {
    case 0:
        mystruct_data = ((struct struct-type-one*) inVar)->data;
        break;
    case 1:
        mystruct_data = ((struct struct-type-two*) inVar)->data;
        break;
    case 2:
        mystruct_data = ((struct struct-type-three*)inVar)->data;
        break;
    }

    // use mystruct_data (and don't forget to check it's not NULL)
}
请注意,您需要先声明变量–您在
switch()
中声明的内容仅限于该
switch()

或者,如果您的数据处理依赖于
类型
,则您可以执行以下操作:

int foo (int type, void* inVar) {    
    switch(type) {
    case 0:
        data_process_1((struct struct-type-one*) inVar);
        break;
    case 1:
        data_process_2((struct struct-type-two*) inVar);
        break;
    case 2:
        data_process_3((struct struct-type-three*) inVar);
        break;
    }
}

如果(正如标签所暗示的)你正在编写C++,你应该使用多态性或模板或其他简化语言的语言特征。p> 现在您所问的问题通常出现在遗留C代码中,因此对于这种语言,使用联合创建是很常见的,这就是您如何做到的(以下当然也是有效的C++):

让我们假设您有3种类型,如问题中所示

struct Type1 {/*some implementation*/};
struct Type2 {/*some implementation*/};
struct Type3 {/*some implementation*/};
然后您将定义一个变量类型,如下所示

struct TVariant
{
    int mtype; 
    union {
        struct Type1 *m1;
        struct Type2 *m2;
        struct Type3 *m3;
    };
};
并以这种方式利用它

int foo (int type, void* inVar) 
{ 
    struct TVariant v;
    switch (type) 
    {
    case TYPE_ONE:
        v.mtype = 1;
        v.m1    = (struct Type1*)inVar;
        break;
    case TYPE_TWO:
        v.mtype = 2;
        v.m2    = (struct Type2*)inVar;
        // .... and so on
    // .....
    }
    // Use your v, actually the correct member of the union in v
}
一些评论:

  • 如果只针对一个函数,则不需要
    TVariant
    的成员
    mtype
    ,只需使用函数参数
    int type
  • TYPE\u ONE
    TYPE\u TWO
    等是映射到类型
    Type1
    Type2
    等的整数常量
  • 它比使用模板更麻烦,也更慢(由于信息丢弃和强制转换)
  • 作为一个更简单的解决方案(对于c++),使用重载可以达到这个目的,因为每个不同版本的
    foo
    对于每个
    类型都有不同的实现
  • 关于如何创建使用的变体对象,有多种变体 联盟,在C++中使用这种方法来实现C.的多态性,你有这样的缺点,所以不需要这些技巧。<李>
  • 最后也是最重要的,主要的缺点是,联合的大小将与其最大的成员类型相同,因此如果(如问题中所暗示的)您只想指向您的类型的指针,那么
    m1
    m2
    m3
    应该是指针,并且联合的大小将始终具有单个指针的大小

您应该使用
break在每个案例之后。另外,除非有必要,否则不要在C++中使用重新解释的情况。在这种情况下,只需使用
dynamic_cast
。Bertrand Meyer选择让Eiffel语言没有
enum
类型,很大程度上是为了避免在程序员面前进行上述愚蠢的类型切换(这是一种已知的反模式)。相反,要实现多态性,请使用多态性。C++支持静态和动态多态性,我怀疑后者使用虚拟成员函数,是您需要的。另一个极端问题是,您使用的是代码>空隙*/COD>,这意味着您丢弃了类型信息。这并不明智:反模式代码完全是关于“撤消”先前不必要的丢弃。只是不要放弃——使用类型。哦,在谷歌上搜索我发现了一个现成的教程:只是为了强调:虽然你可以在Python中这样做,但它也是Python中的反模式。不要写这样的代码。这里的问题是OP想在
switch
子句之后使用
mystruct
。那是不可能的。如果可能的话,我不知道怎么做,当然。但这正是OP想要的。我认为第二段代码足以解决这样的问题。代码的第二部分看起来与我所想的相似。然而,我试图避免编写三个不同的数据处理函数,因为它们都会做相同的事情,只是使用不同的类型。这肯定会奏效的!