www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Strange behavior of opEquals for structs

reply harfel <dadapapa gmail.com> writes:
I am trying to overload opEquals for a struct. The struct will 
hold class objects that define their own opEquals so the default 
bitwise comparison is not good for me.
Everything works nicely if I compare the structs directly. Yet 
when they are used as keys in an associative array, the code 
throws an exception that I do not understand.

My minimal code example is this:

debug import std.stdio;

struct Foo(T) {
	int[T] content;

	bool opEquals(const(Foo!T) that) {
		debug writeln("opEquals called");
		return true;
	}

	alias content this;
}

class Bar { }

void main()
{
	Foo!Bar a = Foo!Bar();
	Foo!Bar b = Foo!Bar();
	assert(a == b);

	debug writeln("This works");

	Foo!Bar[int] x = [1: Foo!Bar()];
	x[1][new Bar] = 1;
	Foo!Bar[int] y = [1: Foo!Bar()];
	y[1][new Bar] = 1;

	assert(x == y);

	debug writeln("This does not work");
}


Here is what I get (using DMD64 D Compiler v2.086.0):

opEquals called
This works
object.Error (0): TypeInfo.equals is not implemented
----------------
??:? bool object._xopEquals(const(void*), const(void*)) [0x49e844]
??:? const pure nothrow  trusted bool 
object.TypeInfo_Struct.equals(const(void*), const(void*)) 
[0x49dcdb]
??:? _aaEqual [0x4a850b]
source/app.d:29 _Dmain [0x46c52f]
Program exited with code 1

Strange thing is that everything works nicely (but produces the 
expected AssertionError) if I comment out Foo.opEquals. What is 
the error message telling me and how can I fix it?

Thanks!!
Jun 19 2019
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 06/19/2019 08:28 AM, harfel wrote:

 Everything works nicely if I compare the structs directly. Yet when they 
 are used as keys in an associative array, the code throws an exception 
 that I do not understand.
You need to define toHash() member function as well: https://dlang.org/spec/hash-map.html#using_struct_as_key Ali
Jun 19 2019
parent harfel <dadapapa gmail.com> writes:
On Wednesday, 19 June 2019 at 17:15:31 UTC, Ali Çehreli wrote:
 On 06/19/2019 08:28 AM, harfel wrote:

 You need to define toHash() member function as well:

   https://dlang.org/spec/hash-map.html#using_struct_as_key

 Ali
Thanks Ali, This fixed my problem, of course. Amazing that such a beginner's mistake still receives attention by one of the gurus :-) harfel
Jun 19 2019