The difference between T[] opIndex() and T[] opSlice()
Steven Schveighoffer
schveiguy at gmail.com
Tue Oct 3 13:07:00 UTC 2023
On Monday, 2 October 2023 at 20:42:14 UTC, Paul Backus wrote:
> On Monday, 2 October 2023 at 20:34:11 UTC, Salih Dincer wrote:
>> In an old version (for example, v2.0.83), the code you
>> implemented in the places where Slice is written above works
>> as desired. In the most current versions, the parameterized
>> opIndexAssign(T value) gives the error:
>>
>>> onlineapp.d(51): Error: function
>>> `onlineapp.Matrix!double.Matrix.opIndexAssign(double value)`
>>> is not callable using argument types `(double, ulong)`
>>> onlineapp.d(51): expected 1 argument(s), not 2
>>
>> **Source:** https://run.dlang.io/is/TPAg5m
>
> I don't know what's wrong in your example but this works for me:
>
> ```d
> struct S
> {
> void opIndexAssign(int value)
> {
> import std.stdio;
> writeln("assigned ", value);
> }
> }
>
> void main()
> {
> S s;
> s[] = 7;
> }
> ```
So in the example linked by Salih, the `opIndex` returns a ref,
which is a valid mechanism to properly do `a[0] = val;`. However,
since `opIndexAssign` exists, the compiler expects that to be
used instead.
Essentially, by naming the slice assign the same operator as
index assign, you have eliminated the possibility for ref
assignment via indexing.
Now, you can define a further `opIndexAssign(T val, size_t idx)`.
However, now you lose capabilities like `a[0]++`, which I don't
think has a possibility of implementing using an `opIndex`
operator, and it would be pretty ugly if you had to.
This seems like a design flaw in the `opIndex` overloading
changes. I would stick with `opSliceAssign` if faced with this
problem (glad it still works!)
It could also be considered a bug but I don't know the overload
implications.
-Steve
More information about the Digitalmars-d-learn
mailing list