Quote from TDPL: "D’s approach to operator overloading is simple: whenever at least one participant in an operator expression is of user-defined type, the compiler rewrites the expression into a regular method call with a specific name. Then the regular language rules apply."

According to the above, I think the following code should work:

struct MyStruct
{
    int _value;
}

ref MyStruct opUnary(string op : "++")(ref MyStruct ms)
{
    ++ms._value;
    return ms;
}

MyStruct opBinary(string op : "+")(MyStruct ms, int value)
{
    return MyStruct(ms._value + value);
}

void main()
{
    MyStruct ms;

    ms.opUnary!"++"();                 // #1: OK
    MyStruct ms2 = ms.opBinary!"+"(1); // #2: OK

    ++ms;                  // #3
    MyStruct ms3 = ms + 1; // #4
}

#3: Error: 'ms += 1' is not a scalar, it is a MyStruct

#4: Error: incompatible types for ((ms) + (1)):
'MyStruct' and 'int'


I'd expect the lines tagged #3 and #4 to be rewritten by the compiler like so:
ms.opUnary!"++"();
MyStruct ms3 = ms.opBinary!"+"(1);

So, the inability to do operator overloading though UFCS must be a compiler bug, right?

Reply via email to