Overloading Logical Operators

Overriding logical operators allows us to compare and order things. Logical operators are binary operators and the same rules apply as for other binary operators.

They can be overridden using both member and non-member functions. Using == as an example, this is how you declare a member function for a point class

bool operator==(const Point &rhs) const;

and this is how you declare a non-member function

bool operator==(const Point &lhs, const Point &rhs);

where lhs is the left hand side of the operator and rhs is the right. Remember that when using member functions, implicit conversions are not going to be done for the left hand operator. You use this by coding

bool equal = point1 == point2;

We don’t need to override all six comparison operators, we can override just two, == and <, and have the compiler generate the other four for us. To do this we need to include the utility header and use the namespace std::rel_ops. As of C++20, this is deprecated in favour of the <=> operator.

Usually implemented as a member function, the three-way compare operator works like the compare method of the string class. Unlike the string::compare method, it returns a value who’s type is comparable to a littoral zero, it will be greater then zero if the lhs is greater than the rhs, equal if they are equal, and less than zero otherwise.

The return type is not an int. It can be one of three types:

  • std::strong_ordering, which gives absolute equality meaning that equivalent items are indistinguishable.
  • std::weak_ordering, which means non-absolute equality, for example “hello” could be considered equivalent to “HELLO” but they are not the same.
  • std::partial_ordering, which can describe incomparable values for a type, for example comparing a double to nan.

In C++20, we only need to declare a spaceship operator to allow us to use all six comparison operators. More than that, we can compare to implicitly convertible value in the left hand position using a member function because the compiler does some magic and swaps the operands around.

If we declare a custom <=> operator, we also need to declare a equals operator as the compiler can no longer generate one for us.

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.