Thanks for the reply Ali. Everything you wrote makes sense, but I think I may have oversimplified the problem in my original email. In general I don't care about what T is when working with Box (or ConcreteBox as it were), but I do care that Box contains a T. Consider this rather contrived example (I'm aware that it's a poorly written function, it just captures my issue.):
bool truthy(Item a, Item b){ if(cast(LongBox) a && cast(LongBox) b){ return (cast(LongBox) a).value && (cast(LongBox) a).value; } else if(cast(CharBox) a && cast(CharBox) b){ return (cast(CharBox) a).value && (cast(CharBox) a).value; } else { return !(a is null || b is null); } } I would much rather write something like: bool truthy(Item a, Item b){ if(cast(Box) a && cast(Box) b){ return (cast(Box) a).value && (cast(Box) a).value; } else { return !(a is null || b is null); } } To be more explicit: By the time I'm writing these if-else/cast statements I already know that my objects are both instances of some type of Box and I also know that the operation(s) I plan to perform on them are valid for any T that box can contain. -tx -- tx.lowtech-labs.org / t...@lowtech-labs.org On Thu, Aug 1, 2013 at 5:06 PM, Ali Çehreli <acehr...@yahoo.com> wrote: > 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 >