Is it possible to make an array of different types in c ++? Or some kind of storage variable in which you can store different types of things? I have several structures, and an array that will dynamically change, and now I would like to somehow add values ​​of different types to it.

Reported as a duplicate by the member αλεχολυτ c ++ 30 May '18 at 6:09 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • one
    Already offered void * (1). There is a generic-oriented way built on a class hierarchy, see the answer @KoVadim. But types should be appropriate - types of classes that inherit from the base class. The built-in types (in java terminology, if I'm not mistaken - "primitive") do not fit. (2) Well, the third way is union (which ideologically is not much different from the first, or, if there is a selector field, from the second (see RTTI). Well, the traditional question is - do you really need it? - alexlz
  • Perhaps what you require is called Algebraic Data Types, but this is no longer C ++, but high-level languages. Perhaps - ada, any ML'i, including Ocaml & F #, Scala, Haskell, etc. - alexlz

2 answers 2

I will propose a third, more with ++ method. What kind of objects you would not have, anyway, they have a common ancestor (yes, void* is a degenerate case and usually speaks of either a strong premature optimization or simply ignorance of the OOP). So, first - you need to write a base class. Other classes for different data are inherited from it. Even if you need to store a string and a number.

Since there is a base class, you can write std::vector<BaseClassName> vec; and there is already an array of objects.

Let them need to print all of them. For this, for each successor, you need to define a method

 friend ostream& operator<<(ostream& os, const YourType& dt); 

And everything, it will be possible to print such code

 for (int i = 0; i < vec.size(); i++) std::cout << vec[i] << std::endl; 

Very simple.

But let it be necessary to save objects and load from a file. Add a virtual method "getObjectType", "getObjectSize", "saveToStream" and "loadFromStream" to the base type. Each heir will have to determine them. Now when saving somewhere like this

 fstream fs; fs.write(vec.size(), sizeof(size_type)); for (int i = 0; i < vec.size(); i++) { int t = vec[i].getObjectType(); size_t s = vec[i].getObjectSize(); fs.write(t, sizeof(t)); fs.write(s, sizeof(s)); vec[i].writeToStream(fs); } 

beautiful?

But loading is a bit more complicated. You will need to store an array of object type matches -> constructor reference. But with a small number of objects, you can if-else or switch

 size_type c; fs.read(c, sizeof(c)); for (int i = 0; i < c; i++) { int t; size_t s; BaseObj* bb; fs.read(t, sizeof(t)); fs.read(s, sizeof(s)); switch (t) { case 1: bb = new IntObject(); break; case 2: bb = new StringObject(); break; //.... default: // unknown object, can skip fs.seekg (s, fs.beg); break; } bb->loadFromStream(fs, s); } 

upd

The main thing to remember is to make the methods virtual, and also to make a virtual destructor. Of course, if classes do not have a common ancestor, then all this will not work.

  • @KoVadim And what is the ancestor of the int type? - alexlz
  • no. This is the base type. But it all depends on the task of the author. Perhaps it would make sense to make an IntObject object. Or maybe the author just needs to think well. - KoVadim
  • @KoVadim but it's worth appreciating the elegance of the crutch that caught on in Java. But after twenty years and in C ++, something similar was going on, along with a bunch of container classes libraries. - alexlz
  • That crutch, what is int and Integer? - KoVadim
  • @KoVadim Of course. Are there three such sweet couples there? - alexlz

Yes, this can be done, but if you need it, then most likely it makes sense to remake the architecture of the program.

This can be accomplished, for example, in the form of a bicycle above the Void.

or a much better option is to use boost

boost :: Any here you can read

in any case, it is better to first think about the architecture.

UPD is actually an example of changing the architecture brought KoVadim ...