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.
/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
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








Erik Rasmussen <i_am_erik yahoo.com>