Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C++ do you need to overload operator== in both directions?

Say I am working with a class:

class Foo{ public:   std:string name;   /*...*/ }/*end Foo*/ 

and I provide an overload for operator==

bool operator==(const Foo& fooObj, const std::string& strObj) {     return (fooObj.name == strObj); } 

Do I also need to re-implement the same logic in reverse?

bool operator==(const std::string& strObj, const Foo& fooObj) {     return (strObj == fooObj.name); } 
like image 358
hehe3301 Avatar asked Nov 14 '18 12:11

hehe3301


People also ask

What function overloads the == operator?

In Python, overloading is achieved by overriding the method which is specifically for that operator, in the user-defined class. For example, __add__(self, x) is a method reserved for overloading + operator, and __eq__(self, x) is for overloading == .

Can we overload == operator in C++?

You can redefine or overload the function of most built-in operators in C++. These operators can be overloaded globally or on a class-by-class basis. Overloaded operators are implemented as functions and can be member functions or global functions. An overloaded operator is called an operator function.

Can comparison operator be overloaded?

You can overload any of these operators, which can be used to compare the objects of a class. Following example explains how a < operator can be overloaded and similar way you can overload other relational operators.


Video Answer


2 Answers

(C++20 onward)

With the acceptance of p1185 into C++20, you don't need to provide more than one overload. The paper made these changes (among others) to the standard:

[over.match.oper]

3.4 - [...] For the != operator ([expr.eq]), the rewritten candidates include all member, non-member, and built-in candidates for the operator == for which the rewritten expression (x == y) is well-formed when contextually converted to bool using that operator ==. For the equality operators, the rewritten candidates also include a synthesized candidate, with the order of the two parameters reversed, for each member, non-member, and built-in candidate for the operator == for which the rewritten expression (y == x) is well-formed when contextually converted to bool using that operator ==. [ Note: A candidate synthesized from a member candidate has its implicit object parameter as the second parameter, thus implicit conversions are considered for the first, but not for the second, parameter. — end note ] [...]

8 [...] If a rewritten candidate is selected by overload resolution for a != operator, x != y is interpreted as (y == x) ? false : true if the selected candidate is a synthesized candidate with reversed order of parameters, or (x == y) ? false : true otherwise, using the selected rewritten operator== candidate. If a rewritten candidate is selected by overload resolution for an == operator, x == y is interpreted as (y == x) ? true : false using the selected rewritten operator== candidate.

The above means that not only do you not need to provide the operator with the order of the operands reversed, you also get != for free! Furthermore, the operator== function can be a member if it makes sense. Though as the note in the first paragraph above says, it being a member or free function will affect implicit conversions so you still need to bear that in mind.


(Upto C++17)

You do if you want to support comparisons where the string is on the left and the Foo is on the right. An implementation won't reorder the arguments to an overloaded operator== to make it work.

But you can avoid repeating the implementation's logic, though. Assuming your operator should behave as expected:

inline bool operator==(const std::string& objA, const Foo& objB) {     return objB == objA; // Reuse previously defined operator } 
like image 97
StoryTeller - Unslander Monica Avatar answered Sep 23 '22 17:09

StoryTeller - Unslander Monica


Yes, you do. Just like in lots of other languages, C++ takes sides and comparisons between two objects of different types will lead to calls to two different comparison operators depending on the order.

Of course, you want them to be consistent and not surprising, so the second should be defined in terms of the first.

like image 34
Matthieu Brucher Avatar answered Sep 21 '22 17:09

Matthieu Brucher