I have two unrelated types of data elements (objects) which I want to hold in two related types of containers, one for each element type. But this seems contradictory - for consistency, it seems that either

(a) the containers should be unrelated through inheritance, or
(b) the elements should be related through inheritance.

The problem with (a) is that I'd like to specify a base class interface for the containers which necessarily relates them through inheritance, and the problem with (b) is that the elements are have very different methods and members so defining a base class for those elements to shoehorn them into the container base class interface would be kind of a hack.

In other words, my elements do not follow the principle of substitutability of objects that are related through inheritance, but their containers do, apart from a single method addelement() which adds the disparate elements to the containers.

What would be a good solution to this dilemma? Has anyone come across such a situation before?

Some remarks (it's not the answer):
Where's this dilemma in that case? Let's remember: all STL containers are not a family of related classes. Yes, they implement (almost) common set of operations - that's all. No such animal as an abstract container class Adam_container with iterators, push_back or/and insert, erase etc members.
Contained elements are data objects (entities), that's true. But a container looks like a processing tool (collect something then iterate something). The F_15 is_a Fighter (inheritance) but a container always is_a container only - where is inheritance (and no dilemma at all ;))?..

Thanks indeed for your replies.

Have you looked into using templates for your containers?

Yes, I certainly did think about that. Although that would generalize my containers somewhat, and I think I will do that at some point, I can't come up with a template solution to address my problem. I could have a generic template<class T> container and have a method addelement(T& elt) but the implemebtation of addelement() depends on the element being added so I'm not sure how that could work.

Some remarks (it's not the answer):
Where's this dilemma in that case? Let's remember: all STL containers are not a family of related classes. Yes, they implement (almost) common set of operations - that's all. No such animal as an abstract container class Adam_container with iterators, push_back or/and insert, erase etc members.
Contained elements are data objects (entities), that's true. But a container looks like a processing tool (collect something then iterate something). The F_15 is_a Fighter (inheritance) but a container always is_a container only - where is inheritance (and no dilemma at all ;))?..

From your STL example I think you're saying that I shouldn't need to relate my containers through inheritance just like the STL ones which aren't related either although their interfaces may be simmilar.

The problem is I need to have a number of different containers which differ not only in the type of elements they hold but also in their implementation details, PencilBox is_a Container just like F_15 is_a Fighter, and I'd like to store these different yet related containers in a vector. Since a vector only holds objects of the same type, this means I'll need a vector of base class pointers which necessarily relates the containers through inheritance.

Now, if we accept this, then the there is a pure virtual addelement() method in the base class interface of the containers which I use to add elements to them, and herein lies my problem: Each derived container class has an addelement() method which takes a different element type. Now, I could make a base class Element for all element types. Then the addelement() method can now just take a generic Element. But the particular element types I'm working with are fundamentally different so I'd like to avoid this, plus I'd have to rewrite other portions related to the elements themselves, etc.

It would be great if I could overload the base class function addelement(void) in a derived class with specific element types as addelement(Pencil& elt) but then the compiler complains that I haven't supplied an implementation of addelement(void) in derived container classes. Another solution would be to forget about the addelement() method in a base class alltogether and just make a different addelement() method in each derived class, but one day someone will write another derived container and forget to include an addelement() method so this pseudocode solution is not ideal either.

Yes, I understand. You want some kind of geterogeneous containers.
Let's consider this problem in pragmatic aspect.
A container (std::vector, for example) is not a museum, it's most likely a workshop. What do you intend to do with this zoo vector where all sorts and kinds of containers and elements collected? No common operations for containers. No common operations for elements. To lump everething together then ...what? As usually this question is like a cold shower for me when the next dream of heterogeneous container visited...

Of course, pragmatically we use class inheritance not only for is_a relationship. For example, an abstract class is an interface, so we may use "implements" but not "is_a" term in that case. Alas, we come back to the common operations set, but addElement(Type1&) and addElement(Type2&) are (and will be) different ops...

None the less, look at some links about heterogeneous containers (by a roundabout way to Boost::Any ;)):
http://www.research.att.com/~bs/bs_faq2.html#containers
http://keithdevens.com/weblog/archive/2003/Jul/01/HeterogeneousContainers
http://www.devx.com/cplus/10MinuteSolution/29757

Hm, I'll definately take a close look at those links, but I don't think I quite need heterogeneous containers. In the end, I don't actually want to store anything and everything in a container. Perhaps my design ideas are flawed, I'll explain in more concrete terms what I'm trying to do in another thread before actually going hetro.

This article has been dead for over six months. Start a new discussion instead.