[Issue 7753] Support opIndexCreate as part of index operator overloading in user-defined types
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Thu Feb 27 21:27:10 UTC 2020
https://issues.dlang.org/show_bug.cgi?id=7753
--- Comment #8 from Steven Schveighoffer <schveiguy at yahoo.com> ---
Just wanted to post something here.
The call a[b][c][d] = 0 results in different calls (_aaGetY now) than x =
a[b][c][d] (_aaGetRvalueX).
So I think H S Teoh is onto the right path. Having a different opIndex
available for assignment (or lvalue manipluation) makes sense and should be
straightforward to define.
Now, to define this a little more concretely, I think opIndexCreate should ONLY
be used when the entire chain of indexing results in a definite lvalue
requirement. This means ONLY opIndexCreate (or AA usage) available in the
expression, and the final "call" should be an opAssign or opOpAssign or
opIndexOpAssign. I would also throw in opUnary that expects mutation (i.e. ++
or --) because it's currently supported by AAs.
Unfortunately, the existing behavior is somewhat inconsistent:
struct S {
int x;
void opUnary(string s : "++")() {++x;}
}
S[int][int] aa;
aa[1][1] = S(1); // ok
aa[2][2].x = 5; // range violation
++aa[3][3]; // range violation
int[int] aa2;
aa2[4] += 3; // ok
++aa2[5]; // ok
void foo(ref int x)
foo(aa2[6]); // range violation
So there is not 100% consistency here. The most rational logical implementation
would just require lvalue usage. But the reality is different.
Also note that ++aa[5] does not match ANY operator that would be on the type of
aa. There is no opIndexOpUnary akin to opIndexOpAssign. And it doesn't work if
your underlying type supports ++. That is an inconsistency that will be tough
to duplicate.
--
More information about the Digitalmars-d-bugs
mailing list