Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
November 17, 2015 opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
In http://dlang.org/operatoroverloading.html#eqcmp it is stated that "If opEquals is not specified, the compiler provides a default version that does member-wise comparison." However, doesn't this only apply to structs, and not objects? The default behaviour of opEquals for objects seems to be "is". A few paragraphs later, in http://dlang.org/operatoroverloading.html#compare, the description of the default version is repeated: "" If overriding Object.opCmp() for classes, the class member function signature should look like: ... If structs declare an opCmp member function, it should have the following form: ... Note that opCmp is only used for the inequality operators; expressions like a == b always uses opEquals. **If opCmp is defined but opEquals isn't, the compiler will supply a default version of opEquals that performs member-wise comparison.** "" Even here, the fact that the described default opEquals behaviour appears to only apply to structs is far from clear. Or am I missing something that should be obvious? Thanks, -- MichaelZ |
November 17, 2015 Re: opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MichaelZ | On 11/17/2015 12:40 AM, MichaelZ wrote: > In http://dlang.org/operatoroverloading.html#eqcmp it is stated that > > "If opEquals is not specified, the compiler provides a default version > that does member-wise comparison." > > However, doesn't this only apply to structs, and not objects? Correct. The behavior for class objects is the following algorithm on the same page: http://dlang.org/operatoroverloading.html#equals This one: bool opEquals(Object a, Object b) { if (a is b) return true; if (a is null || b is null) return false; if (typeid(a) == typeid(b)) return a.opEquals(b); return a.opEquals(b) && b.opEquals(a); } Ali |
November 17, 2015 Re: opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:
> if (typeid(a) == typeid(b)) return a.opEquals(b);
Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ?
But usually when comparing objects one rather cares about the reference itself, so a comparison of the two heap addresses is enough in this case. (meaning same or not same instance, regardless of the their members values).
|
November 17, 2015 Re: opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
Posted in reply to user123ABCabc | On 11/17/15 3:25 PM, user123ABCabc wrote:
> On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:
>> if (typeid(a) == typeid(b)) return a.opEquals(b);
>
> Wow this is terrible to compare two objects in D. The line I quoted
> means that two TypeInfoClass are likely to be allocated, right ?
No, those are immutable stored in the data segment. Fetching them costs only doing the fetch of the class info pointer.
-Steve
|
November 18, 2015 Re: opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote:
> On 11/17/2015 12:40 AM, MichaelZ wrote:
> > In http://dlang.org/operatoroverloading.html#eqcmp it is
> stated that
> >
> > "If opEquals is not specified, the compiler provides a
> default version
> > that does member-wise comparison."
> >
> > However, doesn't this only apply to structs, and not objects?
>
> Correct. The behavior for class objects is the following algorithm on the same page:
>
> http://dlang.org/operatoroverloading.html#equals
>
> This one:
>
> bool opEquals(Object a, Object b)
> {
> if (a is b) return true;
> if (a is null || b is null) return false;
> if (typeid(a) == typeid(b)) return a.opEquals(b);
> return a.opEquals(b) && b.opEquals(a);
> }
Sure, but that defers to the a.opEquals / b.opEquals in many the interesting cases :) Which comes back to the original point: that I feel the documentation I quoted is at least easily misunderstood, if not straight out wrong.
|
November 19, 2015 Re: opEquals default behaviour - poorly documented or am I missing something? | ||||
---|---|---|---|---|
| ||||
Posted in reply to user123ABCabc | On Tuesday, November 17, 2015 20:25:30 user123ABCabc via Digitalmars-d-learn wrote: > On Tuesday, 17 November 2015 at 19:44:36 UTC, Ali Çehreli wrote: > > if (typeid(a) == typeid(b)) return a.opEquals(b); > > Wow this is terrible to compare two objects in D. The line I quoted means that two TypeInfoClass are likely to be allocated, right ? No. As Steven points out. No allocation takes place. > But usually when comparing objects one rather cares about the reference itself, so a comparison of the two heap addresses is enough in this case. (meaning same or not same instance, regardless of the their members values). Really? I would have expected caring about reference equality to be the _rare_ case rather than the common one. And if that's what you want, == isn't the right operator to use anyway. That's what the is operator is for. Regardless, as the code posted by Ali indicates, the free function opEquals that gets called by == for classes does check whether they're the same object first by using the is operator, so all of the other checking is only done if they're not the same object. - Jonathan M Davis |
Copyright © 1999-2021 by the D Language Foundation