我希望能够执行以下操作:
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 ++不喜欢mystruct
如何“交叉初始化”,即根据switch语句的哪个分支使用不同的类型。模板是我们与之搏斗的一个想法,但这很难,因为结构的名称是不同的 - 例如struct intStruct
,struct floatStruct
。这很重要,因为这些结构的大小取决于数据类型。有什么想法吗?
答案 0 :(得分:4)
我不相信它可以直接做你想做的事情(即使它是,它是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()
范围内。
或者,如果您的数据处理取决于type
,那么您可以执行以下操作:
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;
}
}
答案 1 :(得分:3)
如果(正如标签所示)你正在编写c ++,你应该使用多态或模板或其他语言功能来简化这些事情。
现在您在旧版C代码中经常会看到您所问的内容,因此对于这种语言,使用联盟创建variant types很常见,这就是你这样做(以下是有效的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
}
一些评论:
mtype
的成员TVariant
,只需使用函数参数int type
<就可以跟踪类型/ LI>
TYPE_ONE
,TYPE_TWO
等是映射到Type1
,Type2
等类型的整数常量foo
的每个不同版本对每个Type
都有不同的实现m1
,m2
,m3
应该是指针和工会&#39; s大小始终具有单个指针的大小。答案 2 :(得分:1)
你几乎就在那里:
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
}
}
}
你最大的问题可能是并没有在每个箱体周围使用支架。这意味着您的mystruct
变量发生了碰撞。
你可能想要查阅更多关于此类事情的关键词是&#34;歧视联盟。&#34;另请参阅Boost Variant以获得另一种处理它的方法。
答案 3 :(得分:0)
您可以使用以下内容:
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;
}