www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - objects as AA keys

reply captaindet <2krnk gmx.net> writes:
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
Oct 14 2013
next sibling parent reply "Daniel Davidson" <nospam spam.com> writes:
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); }
Oct 15 2013
parent captaindet <2krnk gmx.net> writes:
On 2013-10-15 08:32, Daniel Davidson wrote:
 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
in my use case i don't have multiple objects with the same state, so keying them per obj_ptr (if this is what is happening) seems to be sufficient for me. (the object classes are 3rd party so i cannot overwrite member functions anyway.) /det
Oct 15 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 10/14/2013 10:44 PM, captaindet wrote:

 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)
...
 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?
To be pedantic, hash values are of type size_t.
 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...)
I don't know the definitive answer but my experience was the same when I wrote the following chapter: http://ddili.org/ders/d.en/object.html Contrary to your current need, I say "However, its default behavior is almost never what is desired." :)
 thanks, det
Ali
Oct 15 2013