www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - opIndexDispatch?

reply Yuxuan Shui <yshuiv7 gmail.com> writes:
Hi,

Why is there no opIndexDispatch for overloading a[x].func() ?
Oct 10 2016
next sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Monday, October 10, 2016 19:01:19 Yuxuan Shui via Digitalmars-d-learn 
wrote:
 Hi,

 Why is there no opIndexDispatch for overloading a[x].func() ?
There's opIndex for overloading a[x], and then you can call a function on the return value. If you want some kind of opDispatch on the return value, then the return type will need to implement opDispatch. - Jonathan M Davis
Oct 10 2016
parent reply Yuxuan Shui <yshuiv7 gmail.com> writes:
On Monday, 10 October 2016 at 19:16:06 UTC, Jonathan M Davis 
wrote:
 On Monday, October 10, 2016 19:01:19 Yuxuan Shui via 
 Digitalmars-d-learn wrote:
 Hi,

 Why is there no opIndexDispatch for overloading a[x].func() ?
There's opIndex for overloading a[x], and then you can call a function on the return value. If you want some kind of opDispatch on the return value, then the return type will need to implement opDispatch. - Jonathan M Davis
The opIndex* overloads are used for handling the case where the key is not already in the data structure, right?
Oct 12 2016
parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Wednesday, October 12, 2016 22:45:28 Yuxuan Shui via Digitalmars-d-learn 
wrote:
 On Monday, 10 October 2016 at 19:16:06 UTC, Jonathan M Davis

 wrote:
 On Monday, October 10, 2016 19:01:19 Yuxuan Shui via

 Digitalmars-d-learn wrote:
 Hi,

 Why is there no opIndexDispatch for overloading a[x].func() ?
There's opIndex for overloading a[x], and then you can call a function on the return value. If you want some kind of opDispatch on the return value, then the return type will need to implement opDispatch. - Jonathan M Davis
The opIndex* overloads are used for handling the case where the key is not already in the data structure, right?
opIndex is for overriding the subscript operator so that you can do stuff like foo[bar]. What you actually make the function do is up to you. It could require that the element already be there. It could add the element if it's not there. It could even do something completely unrelated to indexing (though that would generally be considered bad practice). But aside from syntax, the requirements on it are largely just convention. It's good practice to make indexing act similarly to what you'd expect from a built-in type such as an array or associative array, but that's not actually enforced. opIndexUnary, opIndexAssign, and opIndexOpAssign exist to make it possible to do some basic operations on the result of foo[bar] without having to have opIndex return by ref, but assuming that you can return by ref, all of them could be done by having opIndex return by ref. If you were just wrapping an array or trying to mimic an array, then there's a decent chance that you'd just make opIndex return by ref and not overload the others, whereas in the case of something like an associative array, using opIndexAssign makes more sense, because the only way for opIndex to return by ref when opIndex creates the element is if it's default-initialized, whereas if opIndexAssign is used, it can just be created directly with the new value. If you're looking to be able to use opDispatch on the return value without returning by ref and while still affecting something within the object being indexed rather than just affecting the temporary that would be returned by opIndex, then you'll have to do something like return a type that has a pointer to the object being indexed and which implements opDispatch so that foo[bar].baz() uses opDispatch and still is able to acess foo via the pointer in the return value from foo[bar]. There is no opIndexDispatch to combine opIndex and opDispatch. - Jonathan M Davis
Oct 12 2016
parent Yuxuan Shui <yshuiv7 gmail.com> writes:
On Wednesday, 12 October 2016 at 23:14:26 UTC, Jonathan M Davis 
wrote:
 opIndexUnary, opIndexAssign, and opIndexOpAssign exist to make 
 it possible to do some basic operations on the result of 
 foo[bar] without having to have opIndex return by ref, but 
 assuming that you can return by ref, all of them could be done 
 by having opIndex return by ref.
No? If I want to mimics opIndex* by having opIndex return a ref. I would need to create a new entry every time opIndex is used to access a non-existent key, whether the return value is used as a lvalue or not. And opIndex* will solve this problem.
Oct 12 2016
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/10/2016 12:01 PM, Yuxuan Shui wrote:
 Hi,

 Why is there no opIndexDispatch for overloading a[x].func() ?
I could not understand the question fully but would using an element proxy work? import std.stdio; struct ElementProxy { size_t index; void opDispatch(string name, Args...)(Args args) { writefln("%s() is called for index %s with args %s", name, index, [ args ]); } } struct A { auto opIndex(size_t index) { return ElementProxy(index); } } void main() { auto a = A(); a[0].foo(42); a[1].bar("hello", "world"); } Prints foo() is called for index 0 with args [42] bar() is called for index 1 with args ["hello", "world"] Ali
Oct 12 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Thursday, 13 October 2016 at 01:09:06 UTC, Ali Çehreli wrote:
 On 10/10/2016 12:01 PM, Yuxuan Shui wrote:
 Hi,

 Why is there no opIndexDispatch for overloading a[x].func() ?
I could not understand the question fully but would using an element proxy work?
I assume a proxy would indeed work, but it's indeed inconsistent. A proxy would work for opIndexAssign() and friends as well, so why do they exist, when opIndexDispatch() doesn't?
Oct 14 2016
parent Jonathan M Davis via Digitalmars-d-learn writes: