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