The curiously recurring template pattern that David Nehme linked to in the comments might do what you're looking for. It shouldn't keep you from storing objects of the derived class together in the same container. It does look like you're implementing a doubly-linked list with automatic creation of the next item from a given one. (This would invalidate the list from that element to the end unless it is the tail.)
I believe (I haven't tried it yet) you should test a dynamic_cast<>
in the overrides for getNext_noalloc()
to test the next
pointer and call the matching class's construct_impl()
.
// override in derived class
void getNext_noalloc(unsigned x, base* already_allocated_derived_object) {
derived<D1>* p1 = dynamic_cast< derived<D1> >(already_allocated_derived_object);
derived<D2>* p2 = dynamic_cast< derived<D2> >(already_allocated_derived_object);
if(p1 != NULL) {
p1->construct_impl(x, *this, *p1); // 2nd parameter should take base type
} else if(p2 != NULL) {
p2->construct_impl(x, *this, *p2); // 2nd parameter should take base type
}
}
This does assume that the two classes know about each other, so you have to have the function definitions after the classes have been declared, and if construct_impl()
is private or protected, the classes will have to be friend
s.
Using dynamic_cast<>()
should mean you don't need the CRTP after all, but you will have to check each cast to ensure it converts to the correct type.