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.


Reply via email to