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.
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 .
Dot (.) operator can't be overloaded, so it will generate an error.
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:
operator<
, so the type may not necessarily define a operator<
.
operator==
cannot be automatically defined in terms of operator<
operator<
isn't required to compare its arguments. A programmer can define operators for their types to do almost anything to their arguments.
!(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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With