I am trying to get the following code to compile on clang, but it fails with the following error:
error: no member named 'operator<' in the global namespace
struct A
{
int m_test;
A(int test)
: m_test(test)
{
}
friend bool operator<(A left, A right);
};
int main()
{
typedef bool(*TCompare)(A,A);
TCompare compare = &::operator<;
compare(9,7);
}
Clang is correct. For your sample code, the name operator<
intruduced by friend declarations does become the member of global namespace, but it's not visible to name lookup. It can only be found by ADL, but ADL only applies to function-call expressions, while &::operator<
is not.
Names introduced by friend declarations within a non-local class X become members of the innermost enclosing namespace of X, but they do not become visible to lookup (neither unqualified nor qualified) unless a matching declaration is provided at namespace scope, either before or after the class definition. Such name may be found through ADL which considers both namespaces and classes.
To fix it you have to add a matching declaration at global namespace scope. e.g.
struct A
{
int m_test;
A(int test)
: m_test(test)
{
}
friend bool operator<(A left, A right);
};
// add a matching declaration at namespace scope
bool operator<(A left, A right);
int main()
{
typedef bool(*TCompare)(A,A);
TCompare compare = &::operator<;
compare(9,7);
}
bool operator<(A left, A right) {
...
}