This may already have an answer but I've not been able to find an exact case of what I'm attempting.
Suppose you have some generic variant-like class like so (irrelevant details omitted):
/* in hpp file */
struct Base {
void * data;
Base();
virtual ~Base();
// ...
virtual bool Read(...);
}
template <Some_Enum_Class T>
struct Derived : Base {
// T-specific interface to deal with Base::data
bool Read(...); /* implementation in separate cpp file */
}
For reasons specific to the project, it will be possible for such a variant type to refer to containers representing collections of this same variant type. That is, void* data within some Derived will store well-defined types, and those types may eventually lead back to another variation of Derived, and not knowing which ahead of time (it won't be possible during compilation) data must be void*.
It is acceptable for Base to keep track of T if necessary, and it can be set as an instance constant within Derived constructors.
What I'm not sure of is what happens after I create an instance of Derived, and store it (as a Base*) in a void*.
If I take the void* and cast it to Base* (as I won't be able to obtain type information out of runtime nor do I want to beyond what's happening here already), will calling functions like Read correctly use the Derived version despite the fact that the compiler is unable to determine what T is?
In code:
Derived <1> * D = new Derived <1>;
Base * B = (Base*) D; // c-cast for brevity unless this is part of the answer
SendAsVoidPtr( (void*) B ); // at this point the type information is lost
then later
void * arg = ReceiveVoidPtr();
Base * B = (Base*) arg;
Base->Read(...); // which version does this call and why?
I'm guessing (hoping) that the vtable depends only on the address (as void* or Base*), so this should work afaik and call the Derived<1>::Read() function despite the compiler being (probably) unable to determine the type ahead of time, but I'd like to be sure before building on top of this structure...