www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template types in parameter lists

reply "Matthew Dudley" <pontifechs gmail.com> writes:
So this is the general form of what I'm trying to do:


import std.stdio;

class Foo(uint something)
{
   Foo opBinary(string op)(Foo rhs) const
     if (op == "*")
   {
     writeln("calling Foo.*");
   }
}

class Bar : Foo!(3)
{
   // ...
}

class Baz : Foo!(4)
{
   //...
}

void main()
{
   auto bar = new Bar();
   auto baz = new Baz();

   auto foo = bar * baz;
   // errors with
   // tinker.d(28): Error: 'cast(Object)bar' is not of arithmetic 
type, it is a object.Object
   // tinker.d(28): Error: 'baz' is not of arithmetic type, it is 
a tinker.Baz
}


I'm still fairly new to D, and my google-fu has failed me. I 
don't understand this error. If I remove the templating from all 
3 classes, it compiles just fine, and does what I would expect.

It feels like the compiler is maybe ignoring Foo.opBinary? Does 
the compiler not consider Foo!4 to be a valid argument for 
Foo.opBinary? If that's the case, is there a way to tell the 
compiler that Foo.opBinary should accept all specializations for 
a parameter?
Jan 31 2014
parent "bearophile" <bearophileHUGS lycos.com> writes:
Matthew Dudley:

 I'm still fairly new to D, and my google-fu has failed me. I 
 don't understand this error.
You have to remember that an instantiated template creates a totally distinct type. There are few different ways to face your problem, this is one of them: import std.stdio; class Foo(uint N) { Foo opBinary(string op, uint N2)(Foo!N2 rhs) const if (op == "*") { "calling Foo.*".writeln; return new Foo; } } class Bar: Foo!3 {} class Baz: Foo!4 {} void main() { auto bar = new Bar; auto baz = new Baz; auto foo = bar * baz; } Bye, bearophile
Jan 31 2014