operator overloading outside the type

Timon Gehr timon.gehr at gmx.ch
Sat Mar 29 16:00:16 UTC 2025


On 3/29/25 07:09, Walter Bright wrote:
> Thank you, Jonathan. You've said it well. Let's give an example:
> 
> ```
> struct A { int a; alias this = a; }
> 
> struct B { int b; alias this = b; }
> 
> void test()
> {
>      A a;
>      B b;
>      int i = a + b;
> }
> ```
> 
> This compiles today. The statement is replaced with:
> ```
>      int i = a.a + b.b;
> ```
> Now let's suppose some other module is imported, and it declares:
> ```
> int OpAdd(A a, B b) { return 7; }
> ```
> and now:
> ```
>      int i = 7;
> ```
> Don't we have the classic hijacking problem we've worked hard to avoid 
> in D?

Absolutely not.

```
import std.stdio;

struct S{
     void foo(){ writeln("member"); }
}

struct T{
     S s;
     alias this=s;
}

void foo(S s){ writeln("ufcs"); }

void main(){
     T t;
     t.foo();
}
```

Prints "member" (of course).

Your case is not different.

In terms of implementation, just add `opBinary` (and the other operator 
names) to `int`, and it will just work. This should be done anyway, btw. 
Much nicer to be able to consistently use `opCmp` in generic code. 
Actually getting this right and avoiding runtime blowup exponential in 
the opCmp depth is annoying at the moment and may not be obvious to 
everyone.

The only hijacking case with UFCS is if the type adds a member. That may 
hijack existing UFCS calls. This exists already and is hard to avoid 
because people are relying on this behavior.

Anyway, none of this has anything to do with operators if the language 
is designed and implemented in an orthogonal fashion.


More information about the Digitalmars-d mailing list