Struct hash issues with string fields

Ali Çehreli acehreli at yahoo.com
Sat May 26 17:13:16 PDT 2012


On 05/26/2012 12:53 PM, Andrej Mitrovic wrote:
> I don't understand this:
>
> import std.stdio;
>
> struct Symbol { string val; }
>
> void main()
> {
>      int[string] hash1;
>      hash1["1".idup] = 1;
>      hash1["1".idup] = 2;
>      writeln(hash1);  // writes "["1":2]"
>
>      int[Symbol] hash2;
>      Symbol sym1 = Symbol("1".idup);
>      Symbol sym2 = Symbol("1".idup);
>      hash2[sym1] = 1;
>      hash2[sym2] = 1;
>      writeln(hash2);  // writes "[Symbol("1"):1, Symbol("1"):1]"
> }
>
> Why are sym1 and sym2 unique keys in hash2? Because the hash
> implementation checks the array pointer instead of its contents? But
> then why does hash1 not have the same issue?
>
> I can't override toHash() in a struct,

But you can define it.

 > so what am I supposed to do in
> order to make "sym1" and "sym2" be stored into the same hash key?

I don't know all aspects of this issue. I know that there has been 
recent discussions about the hash functions. You may be seeing some 
shortcomings.

What I am pretty sure about is though, once you define toHash(), you 
must also define opCmp() and opEquals() that are all consistent with 
each other.

When I do that, the following code works as you expect:

import std.stdio;

struct Symbol
{
     string val;

     hash_t toHash() const nothrow @safe
     {
         return typeid(val).getHash(&val);
     }

     bool opEquals(const ref Symbol that) const
     {
         return val == that.val;
     }

     int opCmp(const ref Symbol that) const
     {
         return val < that.val ? -1 : (val > that.val ? 1 : 0);
     }
}

void main()
{
     int[Symbol] hash2;
     Symbol sym1 = Symbol("1".idup);
     Symbol sym2 = Symbol("1".idup);
     hash2[sym1] = 1;
     hash2[sym2] = 1;
     writeln(hash2);             // writes [Symbol("1"):1]
}

Ali

-- 
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html


More information about the Digitalmars-d-learn mailing list