On 08/01/2013 04:28 PM, tx wrote:

> Hi All,
> Hoping somebody can provide some help here, I have a set of classes
> that are similar to the following
>
> class Item{}
>
> class Box(T) : Item {
>    T value;
>    //  ...
> }
>
> //Along with some aliases:
>
> alias Box!(long) LongBox;
> alias Box!(char) CharBox;
> //etc.
>
>
>
> I'd like to have a function that operates on instances of Item, but I
> want to specialize the behavior to handle instances of Box
> differently. Is there anyway I can upcast Item to Box without
> specifying the type parameter? In my case I don't really care about
> what T is, just that I'm working with a Box of something. Currently I
> have a whole if-else ladder checking to see if I'm working with an
> instance of each of the aliases and casting appropriately, but I would
> prefer to just write that once. I guess I'm looking for something like
> cast(Box). Is this possible?
>
> To put it another way, is there a D equivalent to the Java syntax of Box<?>

Inserting another layer to the hierarchy is a solution. ConcreteBox is the same as your Box and the new Box in a non-template intermediate class:

class Item{}

class Box : Item{}

class ConcreteBox(T) : Box {
  T value;
  //  ...
}

alias ConcreteBox!(long) LongBox;
alias ConcreteBox!(char) CharBox;
//etc.

// Explicit check
int foo(Item item)
{
    if (cast(Box)item) {
        return 1;
    }

    return 0;
}

unittest
{
    assert(foo(new Item()) == 0);
    assert(foo(new LongBox()) == 1);
    assert(foo(new CharBox()) == 1);
}

// Automatic dispatch for compile-time binding
class Foo
{
    int foo(Item item)
    {
        return 0;
    }

    int foo(Box box)
    {
        return 1;
    }
}

unittest
{
    auto f = new Foo();
    assert(f.foo(new Item()) == 0);
    assert(f.foo(new LongBox()) == 1);
    assert(foo(new CharBox()) == 1);
}

void main()
{}

Ali

Reply via email to