Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I store objects of differing types in a C++ container?

People also ask

How do you store objects of different classes in the same vector?

To use it, you need to specify as a template parameter the base class and the size of the internal chunk of memory that would be enough to fit any of the classes you plan to put inside.

Can list have different data types in C++?

@Dima: Yes, but in the example they are stored by pointer anyway.

Can a vector store objects?

Storing and Accessing Class Objects in a Vector The primary difference in using vectors for storing class objects versus using an array, other than all the differences between vectors and arrays, is how you declare the vector to store class objects.

What is a container in C programming?

A container is an object that stores a collection of objects of a specific type. For example, if we need to store a list of names, we can use a vector .


You could use (or re-implement) boost::any and store instances of boost::any in a container. That would be the safest, since boost::any has probably dealt with much of the edge cases and complexity involved in solving this kind of problem in the general case.

If you want to do something quick and dirty, create a structure or perhaps a union containing members of all potential types along with an enumeration or other indicator of which type is 'active' in the object. Be especially careful with unions as they have some interesting properties (such as invoking undefined behavior if you read the wrong union member, only one of the members can be 'active' at a time, the one that was most recently written to).

I'm curious what you're doing that you need such a construct, though.


Well, the first question would be: Why do you think you need to store objects of different, totally unrelated types in the same container? That seems fishy to me.

If I had the need, I'd look into boost::variant or boost::any.


What you want is called a "hetrogenious container". C++ doesn't technically support them in the STL, but Boost does.

Given that, I think you'll find your answer in this question: how-do-you-make-a-heterogeneous-boostmap


You can use either structures, or classes or std::pair.

[edit]

For classes and structs:

struct XYZ {
    int x;
    string y;
    double z;
};
std::vector<XYZ> container;

XYZ el;
el.x = 10;
el.y = "asd";
el.z = 1.123;
container.push_back(el);

For std::pair:

#include <pair>
typedef std::pair<int, std::pair<string, double> > XYZ;
std::vector<XYZ> container;
container.push_back(std::make_pair(10, std::make_pair("asd", 1111.222)));

You could use a struct that contains all three.

struct Data
{
    int intVal;
    std::string stringVal;
    double doubleVal;
};

Then you could just declare list mycontainer<Data> and use the appropriate value, provided you know what the value type is. If not, add an addition field to the struct that tells you which of the three data types is in use.

struct Data
{
    enum DATATYPE { DT_INT, DT_STRING, DT_DOUBLE } type;

    int intVal;
    std::string stringVal;
    double doubleVal;
};

If you're worried about memory usage, you could probably use a union, though I tend to avoid using them. It might be needless paranoia on my part though.