Thread overview
Operator "+=" overloading for class?
Dec 17, 2023
Ki Rill
Dec 17, 2023
Ki Rill
Dec 17, 2023
Ki Rill
Dec 17, 2023
Adam D. Ruppe
Dec 18, 2023
Ki Rill
Dec 18, 2023
novice2
Dec 18, 2023
Ki Rill
Dec 21, 2023
Ki Rill
Dec 18, 2023
Alexandru Ermicioi
December 17, 2023

I am trying to overload opOpAssign for my class. The code compiles, but it does not seem to be working.

// 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.

December 17, 2023

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 class only.

December 17, 2023

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 class only.

This unittest fails:

// test opOpAssign
auto g = value(0);
g += value(3);
assert(g.data == 3);
December 17, 2023

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

December 18, 2023

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 '+=':

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?

December 18, 2023

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

December 18, 2023

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.

auto opOpAssign(string op)(Value rhs)
{
    this = this + rhs;
    return this;
}

// Error: `this` is not an lvalue and cannot be modified
December 18, 2023

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.

// 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.

Perhaps:

auto opOpAssign(string op)(Value other) {
mixin("this.v " ~ op ~ "= other.v;");
return this;
}
December 20, 2023

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.

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:

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

December 21, 2023

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.