#include <iostream>
#include <fstream>
using namespace std;
class binaryOperators
{
public:
int i;
binaryOperators (int tempI = 0)
{
i = tempI;
}
binaryOperators operator<< (const binaryOperators &right);
};
binaryOperators operator<< (const binaryOperators &left, const binaryOperators &right)
{
cout << "\nOne";
return left;
}
binaryOperators binaryOperators :: operator<< (const binaryOperators &right)
{
cout << "\nTwo";
return *this;
}
int main ()
{
binaryOperators obj;
// Compiler's behavior: This statement calls the overloaded operator << declared inside the class.
obj << 5 << 3 << 2;
// Compiler's behavior: This statement calls the overloaded operator << declared outside the class.
2 << obj;
return 0;
}
I have written the comments inside the main()
function.
What's the reason for this sort of compiler's behavior?
Is this behavior compiler dependent?
GCC on Linux
The behavior you're seeing is caused by const-correctness. The operator<< defined within the class is non-const, so it can only operate on a non-const object or reference, such as obj. The non-member version outside the class has two constant operands.
If you wrote the member version as a non-member, it would look like this:
binaryOperators operator<< (binaryOperators &left, const binaryOperators &right)
{
cout << "\nTwo";
return left;
}
When overload-matching, the compiler chooses the best fit. In the first case, the left operand is non-const, so it chooses the member operator. In the second case, the left operand is an rvalue (temporary binaryOperators), which is referenced as const, so the non-member operator is chosen.
This behaviour makes complete sense:
When a member function exists and matches, then it is a good idea to use it in preference to a free function, otherwise code outside the class could inadvertently break up the class encapsulation (for example, if another member function were to use the operator<<
).
Automatic conversion works by creating a list of candidate functions, then attempting to find conversions for any parameters that require it. In order to find the member function, a conversion would have to happen before building the candidate list, so only the free function is found.