View mode: basic / threaded / horizontal-split · Log in · Help
January 09, 2011
interface function overloading
Isn't it possible to have a hierarchy in interface definitions such that it is
possible to overload according to best interface match?

This now won't compile due to multiple matches.

----
module main;

interface I1{}
interface I2 : I1{}

class C : I2{
 this(){}
}

void func(I1 i){}
void func(I2 i){}

void main(){
 func(new C());
}
----
January 09, 2011
Re: interface function overloading
On Saturday 08 January 2011 22:01:11 %u wrote:
> Isn't it possible to have a hierarchy in interface definitions such that it
> is possible to overload according to best interface match?
> 
> This now won't compile due to multiple matches.
> 
> ----
> module main;
> 
> interface I1{}
> interface I2 : I1{}
> 
> class C : I2{
>   this(){}
> }
> 
> void func(I1 i){}
> void func(I2 i){}
> 
> void main(){
>   func(new C());
> }
> ----

Very little - if anything - in the way of overloading in D works by "best 
match." It pretty much always has to be exact or implicitly convertible and be 
the _only_ option which is implicitly convertible. Sometimes, it can be pretty 
annoying, but it's done to avoid cases where you accidentally call one function 
when you mean another, like you can get in C++ fairly easily.

Take a look at http://www.digitalmars.com/d/2.0/hijack.html

- Jonathan M Davis
January 09, 2011
Re: interface function overloading
== Quote from Jonathan M Davis (jmdavisProg@gmx.com)'s article
> On Saturday 08 January 2011 22:01:11 %u wrote:
> > Isn't it possible to have a hierarchy in interface definitions such that it
> > is possible to overload according to best interface match?
> >
> > This now won't compile due to multiple matches.
> >
> > ----
> > module main;
> >
> > interface I1{}
> > interface I2 : I1{}
> >
> > class C : I2{
> >   this(){}
> > }
> >
> > void func(I1 i){}
> > void func(I2 i){}
> >
> > void main(){
> >   func(new C());
> > }
> > ----
> Very little - if anything - in the way of overloading in D works by "best
> match." It pretty much always has to be exact or implicitly convertible and be
> the _only_ option which is implicitly convertible. Sometimes, it can be pretty
> annoying, but it's done to avoid cases where you accidentally call one function
> when you mean another, like you can get in C++ fairly easily.
> Take a look at http://www.digitalmars.com/d/2.0/hijack.html
> - Jonathan M Davis

I see, cast(ugly:) seems to work.

 func(cast(I2)(new C()));

Thanks.
January 09, 2011
Re: interface function overloading
%u:

>   func(cast(I2)(new C()));

That code smells a bit (http://en.wikipedia.org/wiki/Code_smell ).

Bye,
bearophile
January 09, 2011
Re: interface function overloading
== Quote from bearophile (bearophileHUGS@lycos.com)'s article
> %u:
> >   func(cast(I2)(new C()));
> That code smells a bit (http://en.wikipedia.org/wiki/Code_smell ).
> Bye,
> bearophile

Extract the construction and you get:

----
module main;

interface I1{}
interface I2 : I1{}

class C : I2{
 this(){}
}

void func(I1 i){}
void func(I2 i){}

void main(){
 C c = new C();
 func( cast(I2)c );
}
----

What is the deeper problem in this little snippet?
Or do you mean there is something wrong if you encounter this pattern.

I don't think it's really that much worse than renaming one(or both) of the funcs.
It forces you to cast all class:I2 objects to the func you want called, but all
class:I1 objects already call the correct func.

I think different named funcs is a better solution, but I don't think the cast
solution exemplifies a pattern of indication to a deeper problem.
January 09, 2011
Re: interface function overloading
%u:

> What is the deeper problem in this little snippet?
> Or do you mean there is something wrong if you encounter this pattern.

You are right, sorry :-)

Bye,
bearophile
January 12, 2011
Re: interface function overloading
09.01.2011 15:22, %u пишет:
> == Quote from bearophile (bearophileHUGS@lycos.com)'s article
>> %u:
>>>    func(cast(I2)(new C()));
>> That code smells a bit (http://en.wikipedia.org/wiki/Code_smell ).
>> Bye,
>> bearophile
> Extract the construction and you get:
>
> ----
> module main;
>
> interface I1{}
> interface I2 : I1{}
>
> class C : I2{
>    this(){}
> }
>
> void func(I1 i){}
> void func(I2 i){}
>
> void main(){
>    C c = new C();
>    func( cast(I2)c );
> }
> ----
>
> What is the deeper problem in this little snippet?
> Or do you mean there is something wrong if you encounter this pattern.
>
> I don't think it's really that much worse than renaming one(or both) of the funcs.
> It forces you to cast all class:I2 objects to the func you want called, but all
> class:I1 objects already call the correct func.
>
> I think different named funcs is a better solution, but I don't think the cast
> solution exemplifies a pattern of indication to a deeper problem.
>
In C++ I sometimes have similar problems, especially with multiple 
inheritance. Though, as Jonathan mentioned, those problems are even more 
annoying because of hijacking: you don't always immediately notice them.
Long ago I've decided to always employ conversion methods for such 
cases, which in D might look like this:

class C : I2{
  I1 toI1() { return this; }
  I2 toI2() { return this; }
}

This unclutters the code a bit, i think:

void main(){
  func((new C).toI2()); // compare with func(cast(I2)(new C));
  C c = new C;
  func(c.toI1()); // compare with(cast(I1)c);
}

The calls to conversion methods could be even shorter if they were 
properties, because of omitted parens. Anyway, once I stuck to this 
strategy, it never failed me.
January 12, 2011
Re: interface function overloading
== Quote from Stanislav Blinov (blinov@loniir.ru)'s article
> In C++ I sometimes have similar problems, especially with multiple
> inheritance. Though, as Jonathan mentioned, those problems are even more
> annoying because of hijacking: you don't always immediately notice them.
> Long ago I've decided to always employ conversion methods for such
> cases, which in D might look like this:
> class C : I2{
>    I1 toI1() { return this; }
>    I2 toI2() { return this; }
> }
> This unclutters the code a bit, i think:
> void main(){
>    func((new C).toI2()); // compare with func(cast(I2)(new C));
>    C c = new C;
>    func(c.toI1()); // compare with(cast(I1)c);
> }
> The calls to conversion methods could be even shorter if they were
> properties, because of omitted parens. Anyway, once I stuck to this
> strategy, it never failed me.

I employ this strategy as well but I thought I would like to try the overload
method, just to experiment :)
Top | Discussion index | About this forum | D home