www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ref + operator overloading question

reply "Aleksey" <matklad mail.ru> writes:
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.
Sep 16 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
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.
Sep 16 2013
parent reply "Aleksey" <matklad mail.ru> writes:
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!
Sep 16 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
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.
Sep 16 2013