Hi,
I have 2 interrogations about operator overloading :
1 : is there a convention on how to define conversion/assignment/arithmetic operator between classes that must interact? I wanted a class that can be created/converted/compared/calculated with other types as operands so i began to write all the conversion/assignment/constructors/arithmetic operators for all possible type interraction, but now i get lots of 'ambiguous operators errors' because the compiler finds multiple possible ways to execute the operators between types.
2 : why, for 'commutative' operators (the opeators where the result should not depand on the side of the operands like +,*,==,!= the compiler doesn't find A::operator(B) even if B::operator(A) is defined? Does that mean that the result of those operators can vary depending on which order it is written in?
I can answer the second question: these operators are commutative in "standard" math. But in principle you can define them any way you want. That is why your compiler demands their definitions (and it is unreasonable to define them in un-commutative way).
converson, assignment, and arithmetic are rather different concepts.
For binary arithmetic, I have usually seen one of the two approaches:
One way is to provide no conversion and overload or template the operators for all left/right type combinations. This is necessary if the return type depends on the types of the arguments or if implicit conversion is not suitable.
standard library example: operator+ for complex numbers: there are individual overloads for
Another way is to provide an implicit conversion (i.e. single-argument constructors) and only one form of the operator, accepting the common type of A and B (something both can implicitly convert to) as arguments. In this case the return type has to be the common type of A and B.
standard library example: built-in operator+ for integers
This can sometimes be combined, as in the standard library operator+ for durations:
What i tried so far was to overload the binary operators in my new class. I could do it only one way since the other types i interact with are builtin types and the string class of an other library. That means i had to invert the direction of some expressions that call the operators so that the new class is the left operand. That worked for almost all additions and multiplications, but not for substractions (as i can't always safely change 'a-b' to '-a+b' in all expression for integer overflow reasons).
I created one constructor of my new class to convert each 'other type' to my new type, and did not create any asignment operators from 'other type' to 'new type', and no 'new type' to 'other type' conversion' either. But with that i still get lots of errors when 'new type' items need to be assigned to 'other types'
If i add one conversion operator, i start having 'ambiguous operator errors', so i think i'll create methods looking like SomeType ToSomeType()const; in my new class, so i can manually convert my new type to other types when really needed.
Non member operators should help where i cant change the order of my operations thanks!
An other question. My type can have 'unknown' value, so i created my comparison operators with a custom (char typedef) return type that returns TRUE, NO, AND MAYBE, so that i can return MAYBE when i compare objects and one or more has an 'unknown' value. Hopefully this is not a bad practise?