Having read a few of the threads on this forum, I have a glimmer of hope that there might be a few of you out there that can answer my question.
I confess that my experience with C++ is limited primarily to reading about it and some experimental tinkering. However, with decades of embedded C programming experience, and a long held interest in C++, I think I have a fair grasp of the basics.
I will try to state the issue as simply as possible, and hope that a useful response is possible without first providing a litany of whys and wherefores to describe the context. It's not that I am adverse to sharing more information. I suspect some of you might even find it interesting. But in the interest of efficiency, I'll try first to just get to the point. We can digress later, as much desired.
My problem involves managing lists of value instances of different value types. In theory, the set of value types could be limited to the standard numeric types ( char, unsigned char, int, etc. ). But ultimately, I'd like to be able to include derived types as well. And, toughest of all, I'd like to be able to dynamically ( at run-time ) specify a new value type, so an instance of the new type can also appear in a list. However, the problem is represented well enough by standard types, and if necessary, I could live with a fixed list of value types that are known at compile time.
It seems to me that in C or C++, the only way to make a list of mixed types is to first make them all the same type. This can be done many ways, but in C++ it generally boils down to up-casting a derived class pointer to a base class pointer and then making a list of base class pointers. ( A similar, but more manual technique in C casts addresses to void pointers. )
My goal is to find the most direct and efficient means to access a value instance in the list, as its actual type. I understand that, if I know the type, I can down-cast it and use RTTI to assure that the cast is valid. But I'm not satisfied with this. I want to write code that uses a variable type ID value to determine the type. In effect, I want each value instance to know its own type and behave accordingly.
If I have a list of value instances of a specific type ( for example, int ), I can easily create operator  to provide a reference to any value instance in the list, given an instance ID number. This is extremely convenient, because the value reference can be used as an l_value or an r_value. This pretty much provides normal access to the value instance and supports all its normal behaviors. If the list contained a derived type that, for example, overrides the multiply operator, then that operation would be performed correctly.
It is also possible to associate a type ID number with each value type. This is essentially what RTTI does, and I could potentially use that, or roll my own method. However, it seems that the only way to restore a value to it's actual type, using a type ID number, is by trial and error. That is, some method must be provided to cast a base pointer to successive derived types until a cast succeeds. Worse yet, this must be done within a function that has a fixed return type. So, the result is known only within the function and cannot be "returned".
As an example, assume that:
- A base class is named Number.
- Derived classes named Int, Long and Fraction support value instances of three value types.
- A list of value instances is created for each value type.
- Value instances can be added to each list using a member function and they can be accessed by operator.
- Another list is created for the lists of value instances, with the address of each list up-cast to a Number pointer.
- The Number pointers are accessed by operator with a type ID number as a subscript. ( i.e. Int = 1, Long = 2, Fraction = 3 ).
- A TypInstRef class is created to contain data for value ID and instance ID.
- Finally, a list of TypInstRef instances is created, with capabilities similar to the other lists. In effect, this is a list of mixed types.
Now, assume that I want to access the value associated with type ID = 1 and instance ID = 7.
When I use 1 to access the list of Int values, I get a Number pointer.
I have to cast the Number pointer back to an Int list, before I can access instance 7 of the list ( as an Int value ).
How can I directly cast it, based on the type ID = 1?
I would expect that, ideally, each class derived from the Number class has a static data member that holds its ID value.
This means that the ID value is not visible within a Number instance ( base class ).
So, the Number must be down-cast to a derived class, in order to even test whether the cast is correct.
( I suspect that this is the methodology behind RTTI and C++ casting operators. )
If the type ID is included as a data member of of the Number class, it would be known before the cast. ( An expensive choice in an embedded application. )
But this doesn't help much anyway, because I can't cast a Number pointer to a "1", and still have to somehow transform the type ID to a type cast.
I have imagined many other scenarios, but they all seem to simply move the problem to a different point in the process.
The latest possibility that caught my eye was a form of template definition that contains a numeric constant as a parameter.
Is it possible that I can somehow use this to create my own cast operator for the TypInstRef class?
I'm guessing not, because my instance ID value is not a constant.
However, my understanding of templates is still a little foggy.
Especially when used within a member class. ( A template class defined as a member of an enclosing class. )
I think that one option is to define a huge set of operators for the TypInstRef class to manage every combination ( permutation? ) of value types. This is a very ugly solution for many reasons. Probably the worst thing is that the class must be edited to change the list of supported types.
Perhaps someone can tell me that this is a well-known shortcoming ( or intentional roadblock ) of the C++ language and I need to re-think my design.
Or, perhaps someone knows of a technique that will help me.
When responding, please try to overcome the desire to lecture me on the potential dangers of casting.
Assume for the moment that it is possible for my system design to assure that no invalid casting can occur.
Everything is controlled so that nothing can go wrong... go wrong... go wrong...
I apologize for writing such a long entry.
I just hope it's adequate to prompt a helpful response, or at least lead to some interesting exchanges.
Thanks in advance.