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


Reply via email to