Type polymorphism and type variance

Lubos Pintes lubos.pintes at gmail.com
Wed Dec 5 04:28:32 PST 2012


Sorry maybe I am stupid but where is the value of concrete T?
Or perhaps I completely misunderstood this?
Dňa 5. 12. 2012 4:59 Ali Çehreli  wrote / napísal(a):
> On 12/04/2012 06:42 PM, js.mdnq wrote:
>  > 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
>
> What do you expect to do with x? Unless there is a common interface the
> compiler cannot compile the code without knowing the type of x.
>
> Note that even myGtype!int and myGtype!double are completely different
> types with completely different capabilities.
>
>  > 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.
>
> Alas, the compiler is not available at runtime.
>
>  > Are there any direct oop ways to do this.
>
> The easiest way in OOP would be interfaces and polymorphism. The myGtype
> class template below implements the MyInterface interface and it enables
> us to put different types of objects in a collection.
>
> import std.stdio;
>
> interface MyInterface
> {
>      void foo();
>      MyInterface dup();
> }
>
> class myGtype(T) : MyInterface
> {
>      void foo()
>      {
>           specialOperationFor!T();
>      }
>
>      myGtype dup()
>      {
>          return new myGtype();
>      }
> }
>
> void specialOperationFor(T : double)()
> {
>      writefln("Special operation for %s", T.stringof);
> }
>
> struct S
> {
>      int i;
> }
>
> void specialOperationFor(T : S)()
> {
>      writefln("Special operation for %s", T.stringof);
> }
>
> void main()
> {
>      MyInterface[] objects;
>
>      objects ~= new myGtype!double();
>      objects ~= new myGtype!int();
>      objects ~= new myGtype!S();
>
>      foreach (o; objects) {
>          o.foo();
>      }
>
>      // We can even copy them and the copies have the correct types:
>      foreach (i, o; objects) {
>          auto c = o.dup();
>          writefln("Using the copy of item %s", i);
>          c.foo();
>      }
> }
>
> The output:
>
> Special operation for double
> Special operation for int
> Special operation for S
> Using the copy of item 0
> Special operation for double
> Using the copy of item 1
> Special operation for int
> Using the copy of item 2
> Special operation for S
>
> Ali
>



More information about the Digitalmars-d-learn mailing list