PapaDiHatti
PapaDiHatti

Reputation: 1921

Difference between equivalent and equal for c++20 three way comparison operator?

In c++20 the new three way comparison operator <=> (spaceship operator) is introduced and it can result into four values given below :

  1. std::strong_ordering::less
  2. std::strong_ordering::equivalent
  3. std::strong_ordering::equal
  4. std::strong_ordering::greater

However when I run below code snippet it appears that both equal and equivalent are one and some thing, so I want to know what is the difference between them and in what scenario we should prefer one over another.

#include <iostream>
#include <compare>
int main()
{
    std::strong_ordering res = (2<=>2);
    if(res == std::strong_ordering::equivalent)
    {
        std::cout<<"Equivalent...."<<std::endl;
    }
    if(res == std::strong_ordering::equal)
    {
        std::cout<<"Equal"<<std::endl;
    }
    return 0;
}

O/P :

Equivalent....

Equal

Upvotes: 4

Views: 1199

Answers (4)

kula85
kula85

Reputation: 73

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

For the types that are both EqualityComparable and LessThanComparable, the C++ standard library makes a distinction between equality, which is the value of the expression a == b and equivalence, which is the value of the expression !(a < b) && !(b < a).

Upvotes: 0

Let's say we are discussing an ordering relation that we'll mark as <. Now, equivalence for objects a and b means that both a < b and b < a are false. I.e. neither "compares less than" the other. Equality would mean that they necessarily share the same value, rather than just not being ordered by the relation.

A classic example would be a case-insensitive string type. Where we want to compare the strings lexicographically without taking the case of the letters into account. So we will have for instance have that both "aA" < "aa" and "aa" < "aA" are false. The strings are equivalent under that ordering, but they are certainly not equal.

Upvotes: 3

Nicol Bolas
Nicol Bolas

Reputation: 473272

They are the same thing, both numerically and conceptually. If a comparison generates strong ordering between the items being compared, equivalence and equality are the same.

The reason there are two words for it is because this is not the same for other kinds of ordering. Weak and partial don't have equality at all; they only provide equivalence.

Equivalence means that two objects can compare equal. Equality implies something stronger; if they compare equal, one can be substituted for the other in any const usage:

the property that f(a) == f(b) is true whenever a == b is true, where f denotes a function that reads only comparison-salient state that is accessible via the argument's public const members.

If a type's comparison permits equality (which is a requirement of strong ordering), then it also permits equivalence. So for a strongly ordered comparison, they are the same.

Upvotes: 4

HolyBlackCat
HolyBlackCat

Reputation: 96043

As cppreference says, there is no difference between the two. Hovewer, std::strong_ordering is the only category that defines equal. All other categories only define equivalent.

Linguistically, equivalent means "considered to be equal according to a certain criteria, but may have irrevelant differences", while equal means "indistinguishable". Thus equality implies equivalence.

std::strong_ordering::equal (and equivalent) is normally used when a comparison takes into account all properties of an object:

From cppreference:

implies substitutability: if a is equivalent to b, f(a) is also equivalent to f(b), where f denotes a function that reads only comparison-salient state that is accessible via the argument's public const members. In other words, equivalent values are indistinguishable.

While std::{weak,partial}_ordering::equivalent is intended to be used when different objects are considered to be the same, but may have irrevelant differences.

Upvotes: 5

Related Questions