+ 1

custom comparison for class object and value

Hi We have three different possible comparison as below: class object and class object class object and value value and class object Please refer below code: https://code.sololearn.com/cA12A247a25a Now comparison 1 is working as both are class object and calls overloaded == operator Now comparison 2 is working as RHS is converted to class object using constructor not marked as explicit Is it true? If so, RHS is again a class object constructed by non marked explicit constructor Now, question is that why 3 comparison does not work without friend function? As discussed in option 2 above, RHS is converted to class object , then why value in LHS is not converted to class object and then call overloaded class operator instead of choosing friend function? Feel free to ask for queries in case question is not clear.

24th Jan 2021, 12:55 PM
Ketan Lalcheta
Ketan Lalcheta - avatar
5 ответов
+ 4
When you compare 2 class objects Box b1{1}; Box b2{2}; b1 == b2; it is actually computed as b1.operator==(b2); Similarly, b1 == 10 will be changed to b1.operator==(10). Do you see the pattern? It is like so LHS == RHS is computed as LHS.operator==(RHS) Therefore, 10 == RHS will be computed as 10.operator==(RHS) (not actually because int is not a class and it will give error, but you get the point). This is not valid as there is no overload for the == operator on int that takes an arguement of type `Box` For this reason, you need to globally overload the == operator that takes the LHS as int and RHS as Box. So now when you do 10 == b1 it will be changed to operator==(10, b1)
24th Jan 2021, 1:17 PM
XXX
XXX - avatar
+ 3
[Part 1 of answer] Implicit conversions don’t occur on an object that is calling a method. Consider 2 classes X and Y. *The constructor of class X takes an object of type Y as parameter* X(Y obj); Now suppose there is a method on class X that takes an object of type X as parameter, like so void method(X obj); There is also a method on class Y that takes some other type as parameter void method(sometype obj); Suppose the following objects are constructed X xObj{arg}; X xObj2{arg}; Y yObj{arg}; Now when you call xObj.method(xObj2); It is perfectly valid as X::method requires type X as arg When you call xObj.method(yObj); This is also valid as C++ searches through all constructors of X to find if any of them can be called using arg of type Y. It finds that such a constructor existed and constructs the object implicitly. See this for more on implicit conversion https://en.cppreference.com/w/cpp/language/implicit_conversion Answer to be continued
24th Jan 2021, 4:09 PM
XXX
XXX - avatar
+ 2
[Part 2] But if you try to call yObj.method(xObj); This is invalid. This is where your question comes. Why is yObj not converted to X? To explain this, suppose that you have another class Z which again has a constructor that takes an object of type Y as parameter and has method on it that takes an object of type X class Z{ public: Z(Y obj); void method(X obj); }; Now C++ has *no* way to determine if yObj should be converted to type X or to type Z. To avoid such a case, implicit conversions don't occur on an object which is calling a method. Same way in your code, Box b1{0}; b1.operator==(1); works fine as C++ searches the constructors of Box and finds that there exists a constructor that takes just an int. But int x = 10; x.operator+(b1); Does not work as C++ has no way to determine if x can be converted to Box.
24th Jan 2021, 4:11 PM
XXX
XXX - avatar
+ 2
[Part 3 of answer] It can only do that by searching through each type that exists which can be constructed using an int and has an operator==() declaration that takes a Box, which is obviously not practical as there can be a lot of types (the last statement is only my assumption and there can be some other reason for that not being valid too). It just doesn't make sense to try to call Y.method() and instead end up calling X.method() because they can have entirely different behaviours
24th Jan 2021, 4:13 PM
XXX
XXX - avatar
+ 1
Yeah ...I am getting your point....Question is why 10 on Left side is not converting to object where as 10 on right side is converted as object. Updated existing code with one line added in constructor.... Observe that 5 constructor calls are there... 3 for 3 objects b1 to b3 and two for 10 and 11 values on Right side for comparison with object... This object got constructed and hence object.operator==(obj2) is successful for case 2 .. Now why 10 or 11 values on RHS (case 3) is not calling constructor?
24th Jan 2021, 2:48 PM
Ketan Lalcheta
Ketan Lalcheta - avatar