Structs as Keys for AAs

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Wed Aug 9 18:29:21 PDT 2017


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


More information about the Digitalmars-d mailing list