Reputation: 1947
I was reading CppCoreGuidelines and I stumbled upon something I didn't know before. Basically, it says that I can overload i.e. operator==
outside of a class and it will somehow work for comparing two objects of this class. I did that:
#include <iostream>
class foo
{
public:
int member;
foo() : member(0) {}
};
bool operator==(const foo& lhs, const foo& rhs)
{
return lhs.member == rhs.member;
}
int main()
{
foo c1;
foo c2;
if (c1 == c2)
{
std::cout << "Even" << '\n';
}
}
And well, it actually works. So I started to look for the explanation on the internet. Cuz I can imagine that if I try to compare an object, the compiler searches for the operator==
in this class methods, that is understandable for me. But here I have a function which I guess could be defined in a different file, it's completely independent of the foo
class (only the parameters it takes) and yet it is being recognized as the one to be used for comparison.
So now my question is: How does the compiler or I guess more specifically the linker find this function and it uses it to compare those two objects?
Upvotes: 0
Views: 390
Reputation: 473272
Let's say you have a function bool is_equals(const foo &lhs, const foo &rhs);
. How does the compiler turn is_equals(c1, c2)
into a call to is_equals
?
The answer is exactly the same as for operator==
. When there is no member operator==
for the type(s) of the operands, the compiler attempts to find a non-member operator==
using the operand types. If such a thing exist, then it gets called, If it doesn't exist, then it doesn't get called.
How would the compiler behave if your non-member operator==
overload is in a different file, with no header declaring it in the file you're currently compiling? The answer is the same as before: what happens if you call is_equals
without declaring that such a function exists?
You get a compile error. It doesn't matter if that function is defined in another translation unit; if there is no declaration visible at the time when you try to call the function, you get a compile error.
What happens if two separate files try to define operator==
with different implementations? Again: the same thing that happens if you tried this with is_equal
. You will have violated the One Definition Rule of C++, and thus have invoked undefined behavior. You'll hopefully get a linker error, but there's no guarantee of that.
In short, operator==
is not a special, magical function in C++. It's an unusual name for a function, but it isn't anything special to the compiler or linker. What's special is that c1 == c2
gets converted into a call to operator==(c1, c2)
(which, BTW, is 100% legit C++ code that you can write, though it would only call non-member operator==
). But that's something special about the use of the operator, not of C++ function syntax.
Upvotes: 2