问题
As described here C++11 style SFINAE and function visibility on template instantiation class member functions overshadow free functions. Using a fully qualified name usually works, however I am having a hard time with friend functions of other classes which are declared in-line. Consider the following example:
namespace N {
struct C {
friend int f(const C& c) {
return 1;
}
friend int g(const C& c) {
return 2;
}
};
struct D {
void f() {
g(C{}); // ADL finds this
::N::f(C{}); // not found dispite full qualification
}
};
}
I think I understand what the problem is, as described here What's the scope of inline friend functions? inline friend function are usually found using ADL and not really visible in the enclosing namespace.
So my question is how should I change my code to make this work (aside from renaming one of the f's)?
回答1:
It's because of the friend
liness:
[C++11: 7.3.1.2/3]:
If a friend declaration in a non-local class first declares a class or function the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope [...]. If a friend function is called, its name may be found by the name lookup that considers function from namespaces and classes associated with the types of the function arguments (3.4.2) [i.e. ADL].
The fix is to simply provide that declaration:
namespace N {
struct C {
friend int f(const C& c) {
return 1;
}
friend int g(const C& c) {
return 2;
}
};
int f(const C& c);
int g(const C& c);
struct D {
void f() {
g(C{});
::N::f(C{});
}
};
}
(live demo)
来源:https://stackoverflow.com/questions/24167949/how-do-i-call-an-inline-friend-function-with-the-same-name-as-a-member-function