Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could I use operator == if I only implemented operator <?

People also ask

Can we overload only existing operator?

Rules for Operator Overloading:You can only overload existing operators. You can't overload new operators. Some operators cannot be overloaded using a friend function. However, such operators can be overloaded using member function.

Does STD find use == operator?

std::find. Returns an iterator to the first element in the range [first,last) that compares equal to val . If no such element is found, the function returns last . The function uses operator== to compare the individual elements to val .

Which of the operator Cannot be overloaded in C++?

Dot (.) operator can't be overloaded, so it will generate an error.

Which operator can be overloaded?

An overloaded operator (except for the function call operator) cannot have default arguments or an ellipsis in the argument list. You must declare the overloaded = , [] , () , and -> operators as nonstatic member functions to ensure that they receive lvalues as their first operands.


C++ cannot infer this automatically for a couple of reasons:

  1. It doesn't make sense for every single type to be compared with operator<, so the type may not necessarily define a operator<.
    • This means that operator== cannot be automatically defined in terms of operator<
  2. operator< isn't required to compare its arguments. A programmer can define operators for their types to do almost anything to their arguments.
    • This means that your statement about !(a < b) && !(b < a) being equivalent to a == b may not necessarily be true, assuming those operators are defined.

If you want an operator== function for your types, just define one yourself. It's not that hard :)

// For comparing, something like this is used
bool operator==(const MyType& lhs, const MyType& rhs)
{
    // compare (or do other things!) however you want
}

// ... though it's not the only thing you can do
//  - The return type can be customised
//  - ... as can both of the arguments
const MyType& operator==(int* lhs, const MyType* const rhs)
{
    return lhs;
}

It cannot infer == from < because not all types are ordered, like std::complex. Is 2 + 3i > 1 + 4i or not?

Moreover even in types that are normally ordered you still can't infer the equality from > or <, for example IEEE-754 NaN

double n = std::numeric_limits<double>::quiet_NaN();

std::cout << "NaN == NaN: " << (n == n) << '\n';
std::cout << "NaN < NaN: " << (n < n) << '\n';
std::cout << "NaN > NaN: " << (n > n) << '\n';
std::cout << "NaN != NaN: " << (n != n) << '\n';

They'll all return false except the last one


No. This method works well on number-like objects that is called totally ordered. For all kinds of set/class, no one can guarantee this relation. Even no one can guarantee a operator < would compare something.

So == is nothing else than ==. You may implement == by < but this doesn't work for everyone and C++ standards won't do it for you.


Logically, if !(a < b) and !(b < a) it means a == b. Does c++ infer this automatically? Can I use == if I only implemented

To put what others have stated in mathematical terms: Assuming that you have an operator < that returns bool and defines a strict weak order, and you implement operator == as returning !(a < b) && !(b < a), then this operator defines an equivalence relation consistent with the given strict weak order. However, C++ neither requires operator < to define a strict weak order, nor operator == to define an equivalence relation (although many standard algorithms such as sort may implicitly use these operators and require a strict weak order rsp. equivalence relation).

If you want to define all the other relational operators based on and consistent with your operator <'s strict weak order, Boost.Operators may save you some typing.

Because it's so easy to misuse an operator < that does not meet the standard algorithm's requirements, e.g. by accidentally using it via std::sort, std::lower_bound etc., I recommend to define operator < either as a strict weak order or not at all. The example CodesInChaos gave is a partial order, which does not meet the "transitivity of incomparability" requirement of a strict weak order. Therefore, I'd recommend calling such a relation by a different name, e.g. bool setLess(const MySet &, const MySet &).

Sources:

  • https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings
  • http://en.cppreference.com/w/cpp/concept/Compare

C++ does not infer this automatically. For operator>, operator<= and operator>=, you could use std::rel_ops; this requires only operator<. However, it does not provide operator== in terms of operator<. You can do this yourself like this:

template <class T>
bool operator==(T const& lhs, T const& rhs)
{
    return !((lhs < rhs) or (rhs < lhs));
}

Note that: !((lhs < rhs) or (rhs < lhs)) and !(lhs < rhs) and !(rhs < lhs) are equivalent, mathematically.