Let's look at the questions in order.
Q: How can I create a continuous heterogeneous container?
A: You cannot.
Suppose you used some placement of a new fraud to arrange your objects in memory like this:
[B ][DA ][DB ][B ][B ][DB ][DA ]
How does the iteration mechanism know how far the iteration of the pointer will go from one object to another? The number of bytes from the first element to the second differs from the second to the third.
The reason why adjacent arrays must be uniform is because the distance from one object to the next is the same for all elements. You could try inserting a size into each object, but then you have basically a linked list, not an array (although one with a good location ).
This reasoning leads to the idea of ββusing an array of pointers about which you asked the following question:
Q: Why is it not considered problematic that it is not continuous continuously
A: It is not as slow as you think.
It seems your concern is to follow the following pointers to scattered memory locations. But the cost of following these signs is unlikely to be dominant. Don't dwell on micro-optimizations such as memory layouts until you have strong evidence that they are needed.
Q: Am I forced to do this using carbon paste?
A: No!
Here the problem is most likely in maintainability, and not in performance. Maintainability is much more important, in my opinion, and it's good to think about the early.
For ease of maintenance, you already have a great solution: to support the Base* vector.
If you really want to use multiple vectors, there is an even better way than copy and paste: use a template function like this (not verified):
template <class T> void doStuffToVector(std::vector<T> &vec) { for (std::vector<T>::iterator i = vec.begin(); i!=vec.end(); ++i) { (*i).doStuff(); } }
Then call it for each container:
doStuffToVector(containerA); doStuffToVector(containerB);
If your only concern is maintainability, then either a vector of pointers or a template function should be enough.
Q: Any advice?
A: For starters, ignore performance , at least until constant factors are concerned. Focus on correctness and maintainability.
Then measure the performance . Note that this question did not start with the current and desired speed. You do not have an actual problem to solve!
If after a measurement you make a conclusion too slow, use the profiler to find out where the slow spots are. They are almost never where you think they will be.
Case in point: this whole question and answers focused on iteration, but no one raised the question that the virtual function calls to doStuff are likely to become a bottleneck! virtual function calls are expensive because they are an indirect control flow, which causes serious problems for the pipeline ; indirect access to data is much cheaper because the data cache is usually very efficient for quickly satisfying data access requests.
Q: (Implicit) How would I optimize this?
A: After careful measurement, you may find that this code (the iteration itself, including sending the virtual function; not that inside the doStuff ) is a bottleneck. This should mean that it runs at least billions of iterations.
First, consider algorithmic improvements that will reduce the number of iterations required.
Then exclude the call to the virtual function, for example, by embedding an explicit indicator of the type of the object and testing it with if or switch . This will allow the processor branch predictor to be much more efficient.
Finally, yes, you probably want to combine all the elements into one continuous array to improve locality and eliminate indirect access data. This will mean the elimination of the class hierarchy, so that all objects are of the same type, or the union of all fields into one class and / or using union . This will damage your maintainability program! This is sometimes one of the costs of writing high performance code, but in fact it is only very rarely needed.