On Sun, 09 Jan 2011 11:45:31 -0500, Mafi <[email protected]> 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

Reply via email to