0

is it possible to have some kind of list / array / vector of different structs?

For example in MFC there are CObject and CArray but without MFC:

I can do something alike

std::vector<void*> pVec;
{
  MYSTRUCT m = new MYSTRUCT;
  pArr.push_back(m);
  // looks fine here
}
//what is in my vector now?

Is there something that can handle it?

cnd
  • 32,616
  • 62
  • 183
  • 313
  • You could inherit from a base `class` all the `struct`s involved and take advantage of dynamic polymorphism. – 101010 Aug 13 '14 at 06:48
  • Are the structures you want in the container related? Can you use inheritance? The need to have different (unrelated) structures in a container seems like a design flaw to me. And how would you ever be able to tell what kind of structure a certain pointer is? – Some programmer dude Aug 13 '14 at 06:49
  • @JoachimPileborg they are different but sure it's possible to build some kind of relation – cnd Aug 13 '14 at 06:56
  • Don't just try to force the structures to be related through inheritance, unless they really are. Also, you might want to read [about the XY problem](http://meta.stackoverflow.com/questions/66377/what-is-the-xy-problem), because right now you ask us to help you with a solution you already decided on, but you don't actually tell us *what the problem you want to solve* is. There may be other, perhaps better, solutions. And no, the problem isn't "how to put unrelated structures in a container", the problem is what made you come up with the *solution* "put unrelated structures in a container". – Some programmer dude Aug 13 '14 at 07:00
  • 1
    On the current level of generality, this question is most likely a duplicate of an existing one: http://stackoverflow.com/questions/6274136/objects-of-different-classes-in-a-single-vector, http://stackoverflow.com/questions/3475030/different-types-of-objects-in-the-same-vector-array are two candidates. – jogojapan Aug 13 '14 at 07:03

2 Answers2

4

The obvious preferred approach is to have a std::vector<Base*> to handle polymorphic types.

If you really have completely unrelated types, as it seems to be the case, then boost::any or boost::variant type erasers might be what you are looking for :

std::vector< boost::variant<int, std::string> > vec;
vec.push_back( 21 );
vec.push_back( "hello " );
quantdev
  • 23,517
  • 5
  • 55
  • 88
2

The example that you have given is dangerous. How do you clean up (i.e. delete) what you've allocated? Its type has been erased by being assigned to a void *, so how can the compiler know which operator delete to call?

You can safely go about this at least two different ways:

  • All the objects can inherit from a common base which has a virtual destructor. You can then make a std::vector of std::unique_ptrs to the common base. This has the advantage of being extensible (you can declare new types which derive from the common base and throw them in the container without modifying the container), but has the disadvantage of requiring that you go to the free store (to allocate memory for the std::unique_ptrs to point to).
  • You can use a variant type like boost::variant. This will not require a common base, or allocations on the free store, but it will require that you declare all the types that can possibly be stored in the container when you declare the container (i.e. it's not as easily extensible as an inheritance-based solution).