On 8/9/17 7:31 PM, Q. Schroll wrote:
In [1] it says at 5. that

For this reason, and for legacy reasons, an associative array key is not allowed to define a specialized opCmp, but omit a specialized opEquals. This restriction may be removed in future versions of D.

I'm not completely sure what that means. Does "specialized" mean "user-defined"?

Yes, that's what it means.

I just challenged the spec and found an error by the way: [2]. Apart from that, it compiles.

For 5. I used

struct Key
{
     int id;
     string tag;

     int opCmp(const Key other) const
     {
         return this.id < other.id ? -1 : this.id == other.id ?  0 : 1;
     }

     bool opEquals(ref const Key other) const @safe pure nothrow
     {
         return this.id == other.id;
     }

     size_t toHash() const @safe pure nothrow
     {
         return id;
     }
}

as a key type. To me the part "is not allowed to define a specialized opCmp" is clearly wrong, either a compiler bug or an error in the spec.

You need to read it with the other part "but omit a specialized opEquals". In other words, you must implement opEquals if you implement opCmp. The reason is simple, because opEquals defaults to a comparison of all fields, and most likely if you are defining opCmp, it won't match the default opEquals.

opHash uses opEquals, but does not use opCmp. Therefore, if this restriction wasn't in place, then you may just define opCmp thinking the AA would use it.

Note that in your example, your opEquals is more efficient than opCmp == 0. This is the main reason opEquals is defined differently than opCmp.

Concerning opEquals and opCmp in general: Why isn't opEquals lowered to opCmp returning 0 if not present?

It really should IMO, but that's not how it works. I'm almost positive there's an enhancement request on this somewhere.

-Steve

Reply via email to