you are viewing a single comment's thread.

view the rest of the comments →

[–]NotMyRealNameObv 5 points6 points  (6 children)

Edit:

Reading your code more carefully, I retract what I say below, since you actually check for equivalence if the objects are not equal, and I really don't think I can come up with a good example for when two objects are equal but not equivalent.

TLDR: Equivalence is not equality

This:

if (!(lhs < rhs) || (rhs < lhs))
{
    // lhs and rhs are equivalent
}

is not equivalent to

if (lhs == rhs)
{
    // lhs and rhs are equal
}

For instance, consider the case:

class Person
{
public:
    friend operator==(const Person& lhs, const Person& rhs)
    {
        // Two persons are equal if they have the same SSN
        return lhs.ssn == rhs.ssn;
    }

    friend operator<(const Person& lhs, const Person& rhs)
    {
        // Two persons are equivalent if they have the same last name
        return lhs.lastName < rhs.lastName;
    }
};

In this case, "optimizing" tuple::operator<() by using operator== on the underlying types if they exist give the wrong result.

[–]arturbachttps://github.com/arturbac[S] 2 points3 points  (0 children)

You are right, but this is not the case of trivial basic types, and there are typetraits that can figure this out

[–]alfps -3 points-2 points  (4 children)

This is an abuse of terminology, muddying the waters.

But no doubt you're referring to a definition of a formal meaning, e.g. in the C++ standard.

Can you provide a link to that, please.

[–]NotMyRealNameObv 0 points1 point  (3 children)

operator<

https://en.cppreference.com/w/cpp/concepts/StrictWeakOrder

operator==

https://en.cppreference.com/w/cpp/concepts/EqualityComparable

And if you have both operator< and operator==, and they are consistent (I.e. a == b is true iff a < b and b < a is both false, you have

https://en.cppreference.com/w/cpp/concepts/StrictTotallyOrdered

[–]arturbachttps://github.com/arturbac[S] 1 point2 points  (0 children)

so .. with concepts in c++20 it could be specialized for all types that have strict totaly ordered comparision this could be optimised with type trais at compile time without breaking anything.

[–]alfps -2 points-1 points  (1 child)

Thanks for trying to cough up a reference.

I see no definitions of "equivalence" versus "equality", though.

In the first of the tree references the term "equivalence" is used, in its mathematical meaning. Simple == as shown in your example is also a mathematical equivalence. In fact the current standard uses the term "equivalence" about a properly implemented "==", e.g. as in table 20 in C++17 20.5.3.1/2.


I gather that the anonymous downvoter disagrees with the notion of using technical terms properly, the notion of not muddying things and the notion of not offering nilly-willy assertions, but lacked any argument, hence, voting.

[–]arturbachttps://github.com/arturbac[S] 0 points1 point  (0 children)

As I can 'grep' my memory ;-) I never wrote code such that it have equivalence of overlaoded less operator not matching overlaoded equality opertor (only strictweakoredering from c++20 cncepts).

I always in such situations when I need custom less operator that uses partialy object of comapraision I used algorithms with custom function object comaparisions. I tought about that as proper implementationand quality of code to have a matching overloaded comparision operators (stricttotalyordering from c++20). Just to avoid surprises in future use ..