On Sunday, 15 August 2021 at 20:41:51 UTC, james.p.leblanc wrote:
I have been trying to get a working example of slice assignment operator overloading ... and am befuddled. From the spec (section 20.6.2), the
code below appears:

    struct A
    {
        int opIndexAssign(int v);  // overloads a[] = v
int opIndexAssign(int v, size_t[2] x); // overloads a[i .. j] = v int[2] opSlice(size_t x, size_t y); // overloads i .. j
    }

    void test()
    {
        A a;
        int v;

        a[] = v;  // same as a.opIndexAssign(v);
a[3..4] = v; // same as a.opIndexAssign(v, a.opSlice(3,4));
    }

I have no experience with this, but from a cursory look it seems that that example is wrong.

For starters, the type of `opIndexAssign`'s second parameter must match the return type of `opSlice`. This is easily fixed, but the code still doesn't work.

Further down on the spec page [1], there is this little table:

| op | rewrite |
|-----------------------|------------------------------------------------------|
| `arr[1, 2..3, 4] = c` | `arr.opIndexAssign(c, 1, arr.opSlice!1(2, 3), 4)` | | `arr[2, 3..4] += c` | `arr.opIndexOpAssign!"+"(c, 2, arr.opSlice!1(2, 3))` |

Note the `!1` on `opSlice`. So you need to make `opSlice` a template with an integer parameter.

Working example:

```d
import std.stdio;

struct A
{
    int opIndexAssign(int v, size_t[2] x)
    {
        writeln("opIndexAssign: ", v, ", ", x);
        return v;
    }
    size_t[2] opSlice(size_t i)(size_t x, size_t y)
    {
        return [x, y];
    }
}

void main()
{
    A a;
    int v = 42;
    a[3..4] = v; /* Prints "opIndexAssign: 42, [3, 4]". */
}
```


[1] https://dlang.org/spec/operatoroverloading.html#slice

Reply via email to