Thread overview
ref + operator overloading question
Sep 16, 2013
Aleksey
Sep 16, 2013
Namespace
Sep 16, 2013
Aleksey
Sep 16, 2013
Namespace
September 16, 2013
I get strange type errors in the following code, and I don't
understand why =( Could anybody help?

struct I {
      int i;
      I opBinary(string op)(ref I that)
      if (op == "+") {
          return I(i + that.i);
      }
}

void main() {
      auto a = I(1);
      auto d = a + (a + a);
}

Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I'

If I remove ref or parens around (a+a) the code compiles just
fine.
September 16, 2013
On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote:
> I get strange type errors in the following code, and I don't
> understand why =( Could anybody help?
>
> struct I {
>       int i;
>       I opBinary(string op)(ref I that)
>       if (op == "+") {
>           return I(i + that.i);
>       }
> }
>
> void main() {
>       auto a = I(1);
>       auto d = a + (a + a);
> }
>
> Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I'
>
> If I remove ref or parens around (a+a) the code compiles just
> fine.

opBinary returns a rvalue. But your code accepts only lvalues.
(a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose.
September 16, 2013
On Monday, 16 September 2013 at 20:53:18 UTC, Namespace wrote:
> On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote:
>> I get strange type errors in the following code, and I don't
>> understand why =( Could anybody help?
>>
>> struct I {
>>      int i;
>>      I opBinary(string op)(ref I that)
>>      if (op == "+") {
>>          return I(i + that.i);
>>      }
>> }
>>
>> void main() {
>>      auto a = I(1);
>>      auto d = a + (a + a);
>> }
>>
>> Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I'
>>
>> If I remove ref or parens around (a+a) the code compiles just
>> fine.
>
> opBinary returns a rvalue. But your code accepts only lvalues.
> (a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose.

Thank you! auto ref is exactly what I was looking for!
September 16, 2013
On Monday, 16 September 2013 at 21:01:48 UTC, Aleksey wrote:
> On Monday, 16 September 2013 at 20:53:18 UTC, Namespace wrote:
>> On Monday, 16 September 2013 at 20:43:01 UTC, Aleksey wrote:
>>> I get strange type errors in the following code, and I don't
>>> understand why =( Could anybody help?
>>>
>>> struct I {
>>>     int i;
>>>     I opBinary(string op)(ref I that)
>>>     if (op == "+") {
>>>         return I(i + that.i);
>>>     }
>>> }
>>>
>>> void main() {
>>>     auto a = I(1);
>>>     auto d = a + (a + a);
>>> }
>>>
>>> Error: incompatible types for ((a) + (a.opBinary(a))): 'I' and 'I'
>>>
>>> If I remove ref or parens around (a+a) the code compiles just
>>> fine.
>>
>> opBinary returns a rvalue. But your code accepts only lvalues.
>> (a + a) produce an rvalue so a + (a + a) is the same as lvalue + rvalue and rvalues aren't accepted. You could use auto ref for that purpose.
>
> Thank you! auto ref is exactly what I was looking for!

You should know, that auto ref is only useable for template functions/methods. Maybe this will change, but not in the next years.