www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Operator "+=" overloading for class?

reply Ki Rill <rill.ki yahoo.com> writes:
I am trying to overload `opOpAssign` for my class. The code 
compiles, but it does not seem to be working.

```d
// binary operations have already been implemented for Value
// i need +=, -=, *=, /=
auto opOpAssign(string op)(Value rhs)
{
     mixin("return this" ~ op ~ "rhs;");
}

auto opOpAssign(string op)(in ElementType rhs)
{
     mixin("return this" ~ op ~ "rhs;");
}
```

What am I missing here? Full project code can be found 
[here](https://github.com/rillki/tiny-grad).
Dec 16 2023
next sibling parent reply Ki Rill <rill.ki yahoo.com> writes:
On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 I am trying to overload `opOpAssign` for my class. The code 
 [...]
 
I forgot to mention, it is relevant to [`Value`](https://github.com/rillki/tiny-grad/blob/main/source/rk tgrad/core/value.d) class only.
Dec 16 2023
parent Ki Rill <rill.ki yahoo.com> writes:
On Sunday, 17 December 2023 at 04:15:02 UTC, Ki Rill wrote:
 On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 I am trying to overload `opOpAssign` for my class. The code 
 [...]
 
I forgot to mention, it is relevant to [`Value`](https://github.com/rillki/tiny-grad/blob/main/source/rk tgrad/core/value.d) class only.
This unittest fails: ```d // test opOpAssign auto g = value(0); g += value(3); assert(g.data == 3); ```
Dec 16 2023
prev sibling next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 auto opOpAssign(string op)(in ElementType rhs)
 {
     mixin("return this" ~ op ~ "rhs;");
 }
 ```
check what `op` is. pretty sure it is "+" not "+=" so your element isnt' saved anywhere. also a bit iffy there isn't a member here to work on
Dec 16 2023
parent reply Ki Rill <rill.ki yahoo.com> writes:
On Sunday, 17 December 2023 at 07:05:12 UTC, Adam D. Ruppe wrote:
 On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 [...]
check what `op` is. pretty sure it is "+" not "+=" so your element isnt' saved anywhere. also a bit iffy there isn't a member here to work on
Yes, op is '+'. What do you mean by it isn't saved anywhere? I tried reassigning to `this` and returning it, but it fails. I want to achieve this, but with '+=': ```d auto g = value(0); g = g + value(3); // here it should just create a new instance 'g + value(3)' and save it into 'g' g += value(3); ``` Do you have an advice on how to achieve it?
Dec 17 2023
parent reply novice2 <sorryno em.ail> writes:
On Monday, 18 December 2023 at 03:39:16 UTC, Ki Rill wrote:
 On Sunday, 17 December 2023 at 07:05:12 UTC, Adam D. Ruppe 
 wrote:
 On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 [...]
check what `op` is. pretty sure it is "+" not "+=" so your element isnt' saved anywhere. also a bit iffy there isn't a member here to work on
Yes, op is '+'. What do you mean by it isn't saved anywhere?
your code just return result value, but it should not return but save result to "this" see example at https://dlang.org/spec/operatoroverloading.html#index_op_assignment
Dec 17 2023
parent reply Ki Rill <rill.ki yahoo.com> writes:
On Monday, 18 December 2023 at 04:49:53 UTC, novice2 wrote:
 On Monday, 18 December 2023 at 03:39:16 UTC, Ki Rill wrote:
 On Sunday, 17 December 2023 at 07:05:12 UTC, Adam D. Ruppe 
 wrote:
 On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 [...]
check what `op` is. pretty sure it is "+" not "+=" so your element isnt' saved anywhere. also a bit iffy there isn't a member here to work on
Yes, op is '+'. What do you mean by it isn't saved anywhere?
your code just return result value, but it should not return but save result to "this" see example at https://dlang.org/spec/operatoroverloading.html#index_op_assignment
I get an error, but don't understand why. ```d auto opOpAssign(string op)(Value rhs) { this = this + rhs; return this; } // Error: `this` is not an lvalue and cannot be modified ```
Dec 18 2023
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 18 December 2023 at 14:38:14 UTC, Ki Rill wrote:
 your code just return result value,
 but it should not return but save result to "this"
 see example at 
 https://dlang.org/spec/operatoroverloading.html#index_op_assignment
I get an error, but don't understand why. ```d auto opOpAssign(string op)(Value rhs) { this = this + rhs; return this; } // Error: `this` is not an lvalue and cannot be modified ```
Assigning an object is like copying a pointer. You may think you can try overloading the assignment, but it is [forbidden](https://dlang.org/spec/operatoroverloading.html#assignment): ``` However for class types, identity assignment is not allowed. All class types have reference semantics, so identity assignment by default rebinds the left-hand-side to the argument at the right, and this is not overridable. ``` But you aren't trying to do this. Instead you are trying to reassign the `this` reference, which is a local (and also forbidden). Think about it a second, your `this + rhs` is going to allocate a *new* object. Then if the assignment to the local `this` parameter succeeded, what happens outside the member function? The true reference that is calling this will not be updated! The only way to do this I can see is to reimplement for op=, or maybe perform the operation and swap the guts out. -Steve
Dec 19 2023
parent Ki Rill <rill.ki yahoo.com> writes:
On Wednesday, 20 December 2023 at 02:56:24 UTC, Steven 
Schveighoffer wrote:
 Instead you are trying to reassign the `this` reference, which 
 is a local (and also forbidden). Think about it a second, your 
 `this + rhs` is going to allocate a *new* object. Then if the 
 assignment to the local `this` parameter succeeded, what 
 happens outside the member function? The true reference that is 
 calling this will not be updated!

 The only way to do this I can see is to reimplement for op=, or 
 maybe perform the operation and swap the guts out.

 -Steve
Thank you for such a detailed explanation! That does make sense.
Dec 20 2023
prev sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Sunday, 17 December 2023 at 04:13:20 UTC, Ki Rill wrote:
 I am trying to overload `opOpAssign` for my class. The code 
 compiles, but it does not seem to be working.

 ```d
 // binary operations have already been implemented for Value
 // i need +=, -=, *=, /=
 auto opOpAssign(string op)(Value rhs)
 {
     mixin("return this" ~ op ~ "rhs;");
 }

 auto opOpAssign(string op)(in ElementType rhs)
 {
     mixin("return this" ~ op ~ "rhs;");
 }
 ```

 What am I missing here? Full project code can be found 
 [here](https://github.com/rillki/tiny-grad).
Perhaps: ```d auto opOpAssign(string op)(Value other) { mixin("this.v " ~ op ~ "= other.v;"); return this; } ```
Dec 18 2023