operator overloading outside the type

Steven Schveighoffer schveiguy at gmail.com
Sat Mar 29 16:31:08 UTC 2025


On Saturday, 29 March 2025 at 06:09:24 UTC, 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?

No? It's the same as UFCS:

```d
struct S {
     void foo() { writeln("S"); }
}

struct T {
     S s;
     alias s this;
}

void foo(ref T t) { writeln("UFCS"); }

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

The basic rule should *always* be, if some expression compiles 
based only on the types involved in the expression, then adding 
an import shouldn't change anything.

This goes for member functions, alias this, etc. Hijacking 
something inside the type from outside the type should not be 
allowed.

And the overload rules should suffice as well -- if you have an 
overload set inside the type, it trumps any overload set outside 
the type. This goes for operators too.

>
> We could lather up with some complicated rules to disambiguate 
> this, but we run the risk of becoming C++, where people don't 
> understand how it works and just bash at it until it appears to 
> do what they want.

One reason why I rarely propose things in D these days is because 
the parade of C++ bogey-straw-men come out every time, which have 
nothing to do with the proposal.

If you insist on continuing this I'll drop it, I have much better 
things to do with my time.

-Steve


More information about the Digitalmars-d mailing list