On 12/05/2012 04:28 AM, Lubos Pintes wrote:

> where is the value of concrete T?
> Or perhaps I completely misunderstood this?

Maybe I misunderstand you. :) Are you pointing out that the class template that I have shown did not have any member variables? If so, they can have anything they want.

I have changed the program to include different members and even specialization (for dchar):

import std.stdio;

/* This defines what I want to do with my objects: */
interface MyInterface
{
    void foo();

    /* This is just a silly function to demonstrate that copying an object
     * must be the responsibility of that object because we do not know the
     * concerete type at this level. */
    MyInterface dup();
}

/* A class template that implements the interface */
class myGtype(T)
    if (!is(T == dchar))
  : MyInterface
{
    /* Here is a concrete value: */
    T value;

    /* The implementation can be arbitrarily complex for different T: */
    static if (is (T == S)) {
        S[string] aa;
    }

    this(T value)
    {
        this.value = value;

        static if (is (T == S)) {
            aa["hello"] = value;
        }
    }

    void foo()
    {
        /* This demonstrates how operations that depend on T can be used
         * inside this class template.
         *
         * specialOperationFor() could alternatively be a member function
* template but I find it simpler when it is a free-standing function.
         */
        specialOperationFor!T(value);
    }

    /* This one simply uses 'value'. It could do anything else. */
    myGtype dup()
    {
        return new myGtype(value);
    }
}

/* It is possible to implement a specialization of the type completely
 * separately: */
class myGtype(T)
    if (is(T == dchar))
    : MyInterface
{
    void foo()
    {
        writeln("Inside myGtype!dchar.foo");
    }

    myGtype dup()
    {
        return new myGtype();
    }
}

void specialOperationFor(T : double)(double d)
{
    writefln("Special operation for double: %s", d);
}

struct S
{
    int i;
}

void specialOperationFor(T : S)(S s)
{
    writefln("Special operation for S: %s", s);
}

void main()
{
    MyInterface[] objects;

    objects ~= new myGtype!double(1.5);
    objects ~= new myGtype!int(42);
    objects ~= new myGtype!S(S(100));
    objects ~= new myGtype!dchar();

    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();
    }
}

Ali

Reply via email to