www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Type polymorphism and type variance

One thing I've always struggled with in oop is how to deal with 
storing generic types.

A very simple example is, suppose you had to design a way to 
store generic types.

class myGtype(T) { }

...

myGType[] gcollection;  // should store various types such as 
myGtype!int, myGtype!myobj, etc.., possibly even other things 
like myotherobj, etc..

Obviously we can't store different types in a homogenous array.  
I know D has the ability to use variant types that basically 
overcome this. I imagine it is very inefficient to do it this way?

In my mind, it seems like one could never get around the issue 
without storing type information along with the data because the 
compiler will eventually need to know the type information to 
know how to deal with the data?

e.g.,

auto x = gcollection[i]; // x's type is not determined

auto x = cast(myGtype!int)gcollection[i]; // x's type is forced 
to be myGtype!int, but may not be if gcollection is heterogeneous.

If we stored type information along with the data then we could 
use it to cast to the correct type and make the compiler happy. 
This seems like a rather inefficient way.


Are there any direct oop ways to do this. If, for example, I make 
a wrapper class in which I can create a homogenous array of, but 
somehow the wrapper class managed the heterogeneous nature of the 
types, then it might work. But it seems to me, no matter how one 
tries to make it work, it is impossible(at least efficiently).

In my specific case I am wanting to simply store objects in an 
array of the type myObject!T where T could be any type so I can 
access functions in the type(which unfortunately depend on the 
type).

e.g.,

class myObject(T)
{
   void SetValue(T v) { }
}

....


myObject!?[] arr;     // Not possible
arr[0].SetValue(x)    // But what I am wanting to do.

In fact, I'll have some way to always cast x to the correct 
type(or at least, if not, throw an error).


My question:

Is what I've discussed above basically doable with plan old OOP 
using some design pattern and not some fancy compiler or 
"tricks/hacks"? Basically, am I missing something obvious or is 
the problem actually difficult and requires special methods(like 
std.variant)?
Dec 04 2012