I would appreciate your help!
Which data structure is used to implement heterogeneous array in C or C++ ? The array may contain any standard data types like int,float, char, string etc...
As ravi mentions, the appropriate data structure is called a tag-union (also called variant record). One way to implement it is this:
typedef union {
int tag;
struct {
int tag;
int val;
} int_;
struct {
int tag;
double val;
} double_;
} object;
Then you can make an array of these.
object arr[5];
You use the tag
field to indicate which union member is in use. Typically with an enum
.
enum type { INT, DOUBLE };
Then set the tag when creating the object, and check the tag before accessing. This can be encapsulated by using constructor functions.
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;
}
And you usually want to use a switch
on the tag for accessing, writing a different case for each type.
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;
}
}
Or in some circumstances, you may want to fold the array into a single type so it can be accessed without checking the tag each time.
for (i = 0; i < sizeof arr/sizeof*arr; i++)
if (arr[i].tag == INT)
arr[i] = new_double(arr[i].int_.val);
There is no such array in c++ which can store elements of different types nor there is container in stl. Although there's one way to store different element in a container but condition is those types should be related through inheritance.
In C there's a concept called tagged union which can store different types giving tag as a means to specify which variable is actually there.
One more way to do this is using an array of void* pointers. Although that would be quite ugly C++. This would not be truly heterogeneous as you are using a type of pointer that any pointer can be cast into. It is similar to making a collection of base class type and then storing objects of derived classes.
This I got from Stroustrup article:-
If you need a heterogeneous container in C++, define a common interface for all the elements and make a container of those. For example:
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
Apart from that Boost::Any can also be used:-
vector<Any> v;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With