opEquals for structs

Steven Schveighoffer schveiguy at yahoo.com
Mon Jan 10 08:29:49 PST 2011


On Sun, 09 Jan 2011 11:45:31 -0500, Mafi <mafi at 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


More information about the Digitalmars-d mailing list