Thread overview
opAssign for most struct assignment calls not executed
Nov 23, 2017
Timoses
Nov 23, 2017
Adam D. Ruppe
Nov 23, 2017
Rene Zwanenburg
Nov 23, 2017
Timoses
November 23, 2017
What am I missing?

import std.stdio;

struct A
{
    int value;

    A opAssign(A a)
    {
        writeln(" Assigning");
        return this;             // I know this makes little sense, just for illustration
    }
}

class B
{
    A member;

    this(A a)
    {
        this.member = a; // specifically aiming towards this assignment...
    }
}

void main()
{
    A a = A(1);
    A aa = A(2);

    A aaa = a;

    auto clas = new B(a);

    writeln("Only this works:");
    aaa = a;
    writeln("or");
    A aaaa;
    aaaa = aa;
}


Output:
Only this works:
 Assigning
or
 Assigning


Note that before "Only this works:" nothing was written.

How can I overwrite the opAssign operator??
I'm sure I'm missing something...
November 23, 2017
On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
>     A member;
>
>     this(A a)
>     {
>         this.member = a; // specifically aiming towards this assignment...


That's not assignment, that's construction.

opAssign is only called when you assign over a struct object that already exists. If there isn't an existing object in the variable already, it instead calls a constructor.

A a = A(); // construction, there is no existing a to call
A a; // construction done here...
a = x; // so this is now assignment over the existing object


Sometimes, they look the same, as in your case, but since you are assigning a member for the first time inside a constructor, it still counts as construction of the child object instead of assignment over an existing object.

November 23, 2017
On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
>     A aaa = a;

That's initialization, not assignment, which is subtly different. It will call the postblit on aaa instead of opAssign. A postblit can be defined this way:

this(this)
{

}

There is no way to access the original a from the postblit. All fields have already been copied, you can use it to duplicate reference types, increment reference counts, and other things like that.
November 23, 2017
On Thursday, 23 November 2017 at 15:45:17 UTC, Rene Zwanenburg wrote:
> On Thursday, 23 November 2017 at 15:26:03 UTC, Timoses wrote:
>>     A aaa = a;
>
> That's initialization, not assignment, which is subtly different. It will call the postblit on aaa instead of opAssign. A postblit can be defined this way:
>
> this(this)
> {
>
> }
>
> There is no way to access the original a from the postblit. All fields have already been copied, you can use it to duplicate reference types, increment reference counts, and other things like that.

Wow, that's great! Thanks for the clarification you two!

For reference:
https://dlang.org/spec/struct.html#struct-postblit
http://ddili.org/ders/d.en/special_functions.html