Thread overview
Classes don't inherit opIndex(Assign)
Sep 08, 2005
Ben Hinkle
September 08, 2005
Tried to make a class with multiple opIndex-structures. It only works when you overload the operator with the same number of arguments or don't use inheritance.

Here's some example code:

class A { int opIndex(int a) { return a; } }
class B:A { int opIndex(int a, int b) { return a+b; } }

void main() {
	B b = new B();
	assert(b[2] == 2);
	assert(b[2,4] == 6);
}

BTW, would it be easy to make the latter opIndex support the more common array syntax (ie. b[2][4])? It would certainly make the transition between arrays and classes a lot smoother, just like with public members and properties.
September 08, 2005
"Jari-Matti Mäkelä" <jmjmak@invalid_utu.fi> wrote in message news:dfpkqr$2ub2$1@digitaldaemon.com...
> Tried to make a class with multiple opIndex-structures. It only works when you overload the operator with the same number of arguments or don't use inheritance.
>
> Here's some example code:
>
> class A { int opIndex(int a) { return a; } }
> class B:A { int opIndex(int a, int b) { return a+b; } }
>
> void main() {
> B b = new B();
> assert(b[2] == 2);
> assert(b[2,4] == 6);
> }

That is by design. Superclass methods do not participate in overloading by
default. It works as you expect if you instead write B as
class B:A {
  alias A.opIndex opIndex;
  int opIndex(int a, int b) { return a+b; }
}
using aliases to explicitly say that A's opIndex overloads B's opIndex.

> BTW, would it be easy to make the latter opIndex support the more common array syntax (ie. b[2][4])? It would certainly make the transition between arrays and classes a lot smoother, just like with public members and properties.


September 08, 2005
Ben Hinkle wrote:
> "Jari-Matti Mäkelä" <jmjmak@invalid_utu.fi> wrote in message news:dfpkqr$2ub2$1@digitaldaemon.com...
> 
>>Tried to make a class with multiple opIndex-structures. It only works when you overload the operator with the same number of arguments or don't use inheritance.
>>
>>Here's some example code:
>>
>>class A { int opIndex(int a) { return a; } }
>>class B:A { int opIndex(int a, int b) { return a+b; } }
>>
>>void main() {
>>B b = new B();
>>assert(b[2] == 2);
>>assert(b[2,4] == 6);
>>}
> 
> 
> That is by design. Superclass methods do not participate in overloading by default. It works as you expect if you instead write B as
> class B:A {
>   alias A.opIndex opIndex;
>   int opIndex(int a, int b) { return a+b; }
> }
> using aliases to explicitly say that A's opIndex overloads B's opIndex.

Thanks Ben, now I got it. I think it should be stated more clearly in the specs (http://www.digitalmars.com/d/function.html) that this behaviour includes all kinds of overloaded functions with the same name (not just functions with the same amount of arguments). I though these were somehow more "separate".