I ran the code a couple times and it seems that the member operator wins out.
Yes, the member wins in your example. But not for the reason you think.
Member functions have an implicit object parameter (what this
points to), and the type of the object parameter is determined by the cv-qualifiers at the end of the member function. In this case, your member operator has no cv-qualifiers, so the type of the implicit object is simply A
.
Basically, we have two candidates:
bool operator==(A const&, B const&); // your non-member operator
bool operator==(A&, B const&); // your member operator
The member operator is a better match because the first parameter is a better match - we don't have to take a more const-qualified reference to a
.
If you had made your operator const
(as you generally should), then we'd have these two candidates:
bool operator==(A const&, B const&); // your non-member operator
bool operator==(A const&, B const&); // better member operator
Which are identical, there is no reason to prefer one to the other, and we'd get an ambiguity. There is no rule to prefer a member to a non-member function (or vice versa).