Thread overview
Re: Interfaces and Template Specializations
Jan 11, 2009
Björn T. Herzig
Jan 11, 2009
BCS
Jan 11, 2009
Björn T. Herzig
Jan 11, 2009
Sergey Gromov
January 11, 2009
> Go to the changelog.
> 
> http://www.digitalmars.com/d/2.0/changelog.html

Thanks, downloaded the code but my testcode won't compile

void tester(U)(U u) if(is(U : Plugable) && is(U : Printable))
{
	writefln("U : Printable, Plugable");
	u.plug();
	u.print();
}

void tester(U)(U u)
{
	writefln("Nothing");
}

When calling tester with an object that implements Plugable and Printable it complains that it matches more than one declaration of the template.

Regards,
Björn
January 11, 2009
On Sat, Jan 10, 2009 at 8:51 PM, Björn T. Herzig <raichoo@googlemail.com> wrote:
>> Go to the changelog.
>>
>> http://www.digitalmars.com/d/2.0/changelog.html
>
> Thanks, downloaded the code but my testcode won't compile
>
> void tester(U)(U u) if(is(U : Plugable) && is(U : Printable))

Try changing this to

void tester(U, DUMB=void)(U u) if(is(U : Plugable) && is(U : Printable))

stupid compiler.
January 11, 2009
Reply to Björn,

>> Go to the changelog.
>> 
>> http://www.digitalmars.com/d/2.0/changelog.html
>> 
> Thanks, downloaded the code but my testcode won't compile
> 
> void tester(U)(U u) if(is(U : Plugable) && is(U : Printable))
> {
> writefln("U : Printable, Plugable");
> u.plug();
> u.print();
> }
> void tester(U)(U u)
> {
> writefln("Nothing");
> }
> When calling tester with an object that implements Plugable and
> Printable it complains that it matches more than one declaration of
> the template.
> 
> Regards,
> Björn

try 

void tester(U)(U u) if(is(U : Plugable) && is(U : Printable))
...
void tester(U)(U u) if(is(U : Plugable) && !is(U : Printable))
...

or

void tester(U)(U u)
{
  static if(is(U : Plugable)) u.plug();
  static if(is(U : Printable)) u.print();
}

or something along that line 


January 11, 2009
BCS Wrote:

> 
> try
> 
> void tester(U)(U u) if(is(U : Plugable) && is(U : Printable))
>  ...
> void tester(U)(U u) if(is(U : Plugable) && !is(U : Printable))
>  ...
> 
> or
> 
> void tester(U)(U u)
> {
>    static if(is(U : Plugable)) u.plug();
>    static if(is(U : Printable)) u.print();
> }
> 
> or something along that line
> 
> 

Thanks, the idea with negating some expressions came to me last night ^^. It works.

So that would mean that if i would write something that is more specialized i would have to negate every specialization for the default template?

void tester(U)(U u) if (is(U : Plugable) && is(U : Printable))
void tester(U)(U u) if (is(U : Plugable) && !is(U : Printable))
void tester(U)(U u) if (!is(U : Plugable) && is(U : Printable))
void tester(U)(U u) if (is(U : int) && !is(U : Plugable) && !is(U :Printable))
void tester(U)(U u) if (is(U : char) ..........)
//default template
void tester(U)(U u) if (!is(U : Plugable) && !is(U : Printable) && !is(U : int) && !is(U : char))
etc....

I tried this in a little piece of test code and i need to specialize so much with every specialization i add, that the code becomes very unpleasant to write (see attachment, it won't compile)

Regards,
Björn


January 11, 2009
Sun, 11 Jan 2009 07:11:37 -0500, Björn T. Herzig wrote:

> So that would mean that if i would write something that is more specialized i would have to negate every specialization for the default template?
> 
> void tester(U)(U u) if (is(U : Plugable) && is(U : Printable))
> void tester(U)(U u) if (is(U : Plugable) && !is(U : Printable))
> void tester(U)(U u) if (!is(U : Plugable) && is(U : Printable))
> void tester(U)(U u) if (is(U : int) && !is(U : Plugable) && !is(U :Printable))
> void tester(U)(U u) if (is(U : char) ..........)
> //default template
> void tester(U)(U u) if (!is(U : Plugable) && !is(U : Printable) && !is(U : int) && !is(U : char))
> etc....
> 
> I tried this in a little piece of test code and i need to specialize so much with every specialization i add, that the code becomes very unpleasant to write (see attachment, it won't compile)

Maybe you should choose a different design then?  Use compile-time polymorphism, you seem to do this anyway:

class Test
{
  void print() {...} // printable
}

class Test2
{
  void print() {...} // printable
  void plug() {...} // also pluggable
}

void tester(U)(U u)
{
  static if (!is(typeof(&u.print)))
  {
    static assert(false, "non-printable type");
  }
  else
  {
    static if (is(typeof(&u.plug)))
    {
      u.plug();
    }
    u.print();
  }
}

or maybe use run-time polymorphism--it's hard to tell from this toy case which would be better for the actual task.