Thread overview
opAdd and opAdd_r both match
Dec 11, 2006
Li Jie
Dec 11, 2006
Karen Lanrap
Dec 11, 2006
Li Jie
Dec 11, 2006
Karen Lanrap
December 11, 2006
Test CODE:
---------------------------
class Foo{
    public:
    Foo opAdd(Foo foo){
        return null;
    }

    Foo opAdd_r(Foo foo){
        return null;
    }
}


void main(){
    Foo foo1 = new Foo;
    Foo foo2 = new Foo;
    Foo foo3 = foo1 + foo2;
}

---------------------------
$ dmd zzzz.d
zzzz.d(16): Error: overloads Foo(Foo foo) and Foo(Foo foo) both match argument
list for opAdd


Why dose not select opAdd automatically? like python:

class Foo:
    def __add__(self, v):
        print "call add"
    def __radd__(self, v):
        print "call radd"

foo1 = Foo()
foo2 = Foo()
foo1 + foo2         # call __add__
December 11, 2006
Li Jie wrote:

> Why dose not select opAdd automatically? like python:

Because more than one match is a hint, that the coder might not have noticed, that there are indeed at least two matches, especially when there is a hirarchy of deriving.

In your case one of the overloads is essentially dead code with its possibly harmful impact on maintenance.
December 11, 2006
== Quote from Karen Lanrap (karen@digitaldaemon.com)'s article
> Because more than one match is a hint, that the coder might not have
> noticed, that there are indeed at least two matches, especially when
> there is a hirarchy of deriving.
> In your case one of the overloads is essentially dead code with its
> possibly harmful impact on maintenance.

Thanks.

Sometimes I need it. A new program:

--------------------
class Bar{}

class Foo{
  Bar opAdd(T)(T v){
    return null;
  }

  Bar opAdd_r(T)(T v){
    return null;
  }
}

auto foo1 = new Foo;
auto foo2 = new Foo;
auto bar1 = foo1 + 1; // OK
auto bar2 = 1 + foo1; // OK
auto bar3 = "a" + foo1; // OK
auto bar4 = [1,2,3] + foo1; // OK
auto bar5 = foo1 + foo2 // Not OK
--------------------

How to write opAdd_r? I try to write it:

--------------------
template opAdd_r(T){
  static if (!is(T == Foo)){
    Bar opAdd_r(T v){
      return null;
    }
  }
}
--------------------
Compile failed too:
zzz.d(61): template zzz.Foo.opAdd_r(T) is not a function template
zzz.d(10): template zzz.Foo.opAdd_r(T) cannot deduce template function from
argument types (Foo)


May be I need a NO-MATCH Template Specialization:
------------------
class Foo{
  Bar opAdd_r(T: !Foo)(T v){   // *(T: !Foo)*
    return null;
  }
}
------------------
December 11, 2006
Li Jie wrote:

> May be I need a NO-MATCH Template Specialization:

Because in a real world example you need specializations for every other type, you simply do not provide a specialization for the conflicting type.