www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - opEquals for structs

reply Mafi <mafi example.org> writes:
Just tried to implemnt Perl6-like junctions. Despite template functions 
overloading against varadic and non-variadic (ie T[] and T[]...) does 
not work, why has a struct opEquals to be S.opEquals(ref const(S))? Why 
can't I compare a class against a struct or in  my case a struct against 
an int? I can't even compare a struct against a struct of another type.
I'm curious for the reason of this.

Mafi
Jan 09 2011
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 09 Jan 2011 11:45:31 -0500, Mafi <mafi example.org> wrote:

 Just tried to implemnt Perl6-like junctions. Despite template functions  
 overloading against varadic and non-variadic (ie T[] and T[]...) does  
 not work, why has a struct opEquals to be S.opEquals(ref const(S))? Why  
 can't I compare a class against a struct or in  my case a struct against  
 an int? I can't even compare a struct against a struct of another type.
 I'm curious for the reason of this.

It's an ill-advised design decision that was driven by the requirement to make the "default" opEquals be able to call it's elements' opEquals functions. The reasoning goes, a struct like this: struct S { M m; } where M is another struct or object type, which may define an opEquals, then the default opEquals defined for S should look like this: bool opEquals(ref const(S) other) const { return other.m == m; } Now, what if M did not have an equivalent opEquals signature? Then no comparison could be made. The chosen path to solve this problem is to force all structs to have that type of signature, instead of just barfing on compiling S == S. There is a bug report on this, and I believe it will be fixed eventually. Right now, the focus is on getting 64-bit dmd working. http://d.puremagic.com/issues/show_bug.cgi?id=3659 Note, as a workaround, you can define an opEquals with the *required* signature, and overload it with another. For example, you can do: struct S { M m; bool opEquals(ref const(S) other) const { return other.m == m; } bool opEquals(int other) const { return other == m.asInt; } } But you are SOL if you want to do something like templatize opEquals. Expect the situation to get better. Meanwhile, you can vote for the bug. -Steve
Jan 10 2011