digitalmars.D.learn - Self-referencing template parameters
- Erik Rasmussen (32/32) Mar 20 2006 One way that I have found java's generics to be useful is in doing
- Oskar Linde (15/52) Mar 20 2006 The problem is that this line contains a recursive instantiation:
- Erik Rasmussen (31/51) Mar 20 2006 Thanks, but...
- Erik Rasmussen (4/65) Mar 20 2006 Oops. The problem was the "abstract" on the very first line. Bad Java
One way that I have found java's generics to be useful is in doing something like this: --- public abstract class Animal<T extends Animal<T>> { public abstract T[] procreate(T mate); } public class Monkey extends Animal<Monkey> { public Monkey[] procreate(Monkey mate) { // make sweet monkey love } } --- Although you're not strictly forced to by the compiler, if you make it a policy to always make your template variable the same as your concrete subclass, then you have forced any class that extends Animal to provide a way to "procreate" with its own kind. I seem to be unable to implement this pattern in D. The following doesn't work: --- abstract class Animal(T : Animal!(T)) { abstract T[] procreate(T mate); } --- It doesn't like that template definition on the first line. It says, "template instance does not match any template declaration". Any ideas? Cheers, Erik
Mar 20 2006
Erik Rasmussen skrev:One way that I have found java's generics to be useful is in doing something like this: --- public abstract class Animal<T extends Animal<T>> { public abstract T[] procreate(T mate); } public class Monkey extends Animal<Monkey> { public Monkey[] procreate(Monkey mate) { // make sweet monkey love } } --- Although you're not strictly forced to by the compiler, if you make it a policy to always make your template variable the same as your concrete subclass, then you have forced any class that extends Animal to provide a way to "procreate" with its own kind. I seem to be unable to implement this pattern in D. The following doesn't work: --- abstract class Animal(T : Animal!(T)) { abstract T[] procreate(T mate); } --- It doesn't like that template definition on the first line. It says, "template instance does not match any template declaration". Any ideas?The problem is that this line contains a recursive instantiation: abstract class Animal(T : Animal!(T)) Animal!(T) has to be instantiated before the compiler knows how to what type it is. But if you place a static assert in a place outside what the compiler needs to deduce the type: class Animal(T) { this() { static assert(is(T : Animal)); } public abstract T[] procreate(T mate); } Things work as they should. /Oskar
Mar 20 2006
Oskar Linde wrote:The problem is that this line contains a recursive instantiation: abstract class Animal(T : Animal!(T)) Animal!(T) has to be instantiated before the compiler knows how to what type it is. But if you place a static assert in a place outside what the compiler needs to deduce the type: class Animal(T) { this() { static assert(is(T : Animal)); } public abstract T[] procreate(T mate); } Things work as they should. /OskarThanks, but... test.d --- abstract class Animal(T) { this() { static assert(is(T : Animal)); } public abstract T[] procreate(T mate); } class Monkey : Animal!(Monkey) { public Monkey[] procreate(Monkey mate) { return new Monkey[2]; } } int main(char[][] args) { new Monkey(); } --- When I compile, I get: test.d: variable test.Animal!(Monkey).Animal.this.this abstract cannot be applied to variable test.d:3: variable test.Animal!(Monkey).Animal.this.__result abstract cannot be applied to variable Now what? Line 3 is the "this()" line. Erik
Mar 20 2006
Erik Rasmussen wrote:Oskar Linde wrote:Oops. The problem was the "abstract" on the very first line. Bad Java habit. ErikThe problem is that this line contains a recursive instantiation: abstract class Animal(T : Animal!(T)) Animal!(T) has to be instantiated before the compiler knows how to what type it is. But if you place a static assert in a place outside what the compiler needs to deduce the type: class Animal(T) { this() { static assert(is(T : Animal)); } public abstract T[] procreate(T mate); } Things work as they should. /OskarThanks, but... test.d --- abstract class Animal(T) { this() { static assert(is(T : Animal)); } public abstract T[] procreate(T mate); } class Monkey : Animal!(Monkey) { public Monkey[] procreate(Monkey mate) { return new Monkey[2]; } } int main(char[][] args) { new Monkey(); } --- When I compile, I get: test.d: variable test.Animal!(Monkey).Animal.this.this abstract cannot be applied to variable test.d:3: variable test.Animal!(Monkey).Animal.this.__result abstract cannot be applied to variable Now what? Line 3 is the "this()" line. Erik
Mar 20 2006