感谢您的帮助!
在C或C ++中使用哪种数据结构来实现异构数组?该数组可以包含任何标准数据类型,如int,float,char,string等......
答案 0 :(得分:4)
正如ravi所提到的,适当的数据结构称为标签联合(也称为变体记录)。实现它的一种方法是:
typedef union {
int tag;
struct {
int tag;
int val;
} int_;
struct {
int tag;
double val;
} double_;
} object;
然后你可以制作这些数组。
object arr[5];
使用tag
字段指示正在使用的联合成员。通常使用enum
。
enum type { INT, DOUBLE };
然后在创建对象时设置标记,并在访问之前检查标记。这可以使用构造函数函数进行封装。
object new_int(int i){
object ret;
ret.tag = INT;
ret.int_.val = i;
return ret;
}
object new_double(double d){
object ret;
ret.tag = DOUBLE;
ret.double_.val = d;
return ret;
}
您通常希望在标签上使用switch
进行访问,为每种类型编写不同的案例。
void print_object(object x){
switch(x.tag){
case INT: printf("%d\n", x.int_.val); break;
case DOUBLE: printf("%f\n", x.double_.val); break;
}
}
或者在某些情况下,您可能希望将数组折叠为单个类型,以便每次都可以访问它而无需检查标记。
for (i = 0; i < sizeof arr/sizeof*arr; i++)
if (arr[i].tag == INT)
arr[i] = new_double(arr[i].int_.val);
答案 1 :(得分:1)
c ++中没有这样的数组可以存储不同类型的元素,也不存在stl中的容器。虽然有一种方法可以在容器中存储不同的元素,但条件是这些类型应该通过继承来关联。
在C中有一个称为标记联合的概念,它可以存储不同的类型,给出标记作为指定实际存在哪个变量的方法。
另一种方法是使用void *指针数组。虽然那将是非常难看的C ++。这不是真正的异构,因为你使用的是一种指针,任何指针都可以被强制转换。它类似于创建基类类型的集合,然后存储派生类的对象。
这是我从Stroustrup文章中得到的: -
如果您需要C ++中的异构容器,请为所有元素定义一个公共接口并创建一个容器。例如:
class Io_obj { /* ... */ }; // the interface needed to take part in object I/O
vector<Io_obj*> vio; // if you want to manage the pointers directly
vector< Handle<Io_obj> > v2; // if you want a "smart pointer" to handle the objects
除了Boost :: Any之外,还可以使用: -
vector<Any> v;
答案 2 :(得分:0)
我猜你可以保留一系列指向
的指针void* stuff[size];
const char* str = "hello";
int x = 20;
int *array = malloc(sizeof(int) * 5);
stuff[0] = str;
stuff[1] = &x;
stuff[2] = array;
或者,如果您事先了解所有类型,那么就是一系列联盟。