objects as AA keys

Daniel Davidson nospam at spam.com
Tue Oct 15 06:32:36 PDT 2013


On Tuesday, 15 October 2013 at 05:44:25 UTC, captaindet wrote:
> hi,
>
> i am a bit confused.
>
> the official language ref  ( http://dlang.org/hash-map.html ) 
> states:
> "
> Classes can be used as the KeyType. For this to work, the class 
> definition must override the following member functions of 
> class Object:
> hash_t toHash()
> bool opEquals(Object)
> int opCmp(Object)
> ...
> "
>
> but now i stumbled on 
> http://forum.dlang.org/post/mailman.2445.1354457588.5162.digitalmars-d-learn@puremagic.com
> "
> int[typeof(O)] rc;
> rc[O] = 42;
> auto O2 = O;
> // [...]
> if (auto r = O2 in rc)
>    return *r;
> else
>    return rc[O2] = compute(O2);
>
> IOW explicitly taking the address may not be necessary when 
> doing that kind of things.
> "
>
> and i did a quick test and indeed, it seems to work out of the 
> box - without overriding any member functions. in my use case, 
> i wouldn't be able to modify the class anyway.
>
> so my questions:
>
> why is it working, is it just syntactic sugar for using 
> cast(void*)Obj as key?
>
> what is the danger of using objects as keys? when would it fail?
>
> as it seems to be working against language specs, will this 
> 'feature' eventually be removed?
> (then maybe i should use cast(void*)Obj right away...)
>
>
> thanks, det

Do you have an example where it is really working? The problem of 
not overriding those functions is that maybe you are not getting 
what you think. For example, the code below will print:

[aaa.S:42]
[aaa.S:42, aaa.S:43]

This is probably not what you want. If you don't override the 
functions how is the implementation to know what are equivalent 
keys? Below you would probably expect two S's that are default 
constructed to hit the same key spot in the AA. But this does not 
happen since the implementation does not know you want new S to 
equal new S because there is no opEquals.

Thanks,
Dan

-------------------------

import std.stdio;

class S {
   int[] o = [1,2,3];
}

void main() {
   S O = new S;
   int[typeof(O)] rc;
   rc[O] = 42;
   writeln(rc);
   rc[new S] = 43;
   writeln(rc);
}



More information about the Digitalmars-d-learn mailing list