Thread overview | ||||||
---|---|---|---|---|---|---|
|
March 20, 2006 Self-referencing template parameters | ||||
---|---|---|---|---|
| ||||
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 |
March 20, 2006 Re: Self-referencing template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Erik Rasmussen | 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
|
March 20, 2006 Re: Self-referencing template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Oskar Linde | 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. > > > /Oskar Thanks, 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 |
March 20, 2006 Re: Self-referencing template parameters | ||||
---|---|---|---|---|
| ||||
Posted in reply to Erik Rasmussen | Erik Rasmussen wrote:
> 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.
>>
>>
>> /Oskar
>
>
> Thanks, 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
Oops. The problem was the "abstract" on the very first line. Bad Java habit.
Erik
|
Copyright © 1999-2021 by the D Language Foundation