I think this example best illustrates my question:
namespace N {
class C {
public:
friend bool operator==(const C& c, const C& x) {
return true;
}
friend bool f(const C& c, const C& x) {
return true;
}
};
class D {
public:
bool operator==(const D& x) {
bool a = C{} == C{}; // this works
return true;
}
bool f(const D& x) {
bool a = f(C{}, C{}); // this does not work
return true;
}
};
}
I have always viewed overloaded operators as being just like function except for the 'calling syntax' if you will. I just noticed the above difference however in ADL or name lookup rules (I don't know which one).
Can someone explain why the bool operator==(const C& c, const C& x)
is found but the bool f(const C& c, const C& x)
is not?
Your
D::f
is hidingC::f
; if you rename the latter toC::g
and adjust the call then it works fine (showing that the function can be found and accessed just fine).Your code isn't actually directly calling the operator functions, but this is done for you by the language. Consequently you're not using the name of the operator function, so no name hiding applies.
If you write
operator==(C{}, C{})
(instead ofC{} == C{}
), then you'll see the same behaviour asf(C{}, C{})
(demo).So, when you say "I have always viewed overloaded operators as being just like function except for the 'calling syntax' if you will", you've already hit the nail on the head.
Here's some standardese for you:
(The [qualified] operator-function-id here is
::N::C::operator==
.)