Difference between friends defined in class and outside: bug or feature?
Consider:
struct Y {
Y(float f) : f(f) {}
float f;
};
struct X {
X(Y y) : i(y.f) {}
int i;
friend bool operator==(X x1, X x2) {
return x1.i == x2.i;
}
};
int main()
{
return Y(1) == Y(2); // ERROR
}
This throws the following error in MSVC and similar for Clang:
'==': candidate function(s) not accessible
could be the friend function at '..\main.cpp(11)' : '==' [may be found via argument-dependent lookup]
If I translate the definition of the friend function from the class:
struct X {
X(Y y) : i(y.f) {}
int i;
friend bool operator==(X x1, X x2);
};
inline bool operator==(X x1, X x2)
{
return x1.i == x2.i;
}
The main()
above expression compiles fine.
Is it standard or buggy? If provided: why?
source to share
It's a C ++ weirdness.
[C++14: 11.3/7]:
[..] A friend function defined in a class is in the (lexical) scope of the class in which it is defined. A friend function defined outside a class is not (3.4.1).
This means that the operator call will work if you did it from within a member function, but not otherwise . Although it is not a member.
Argument dependent lookup is about the only other way to call it, but it's useless to you, because both arguments are X
s, not Y
s.
Your workaround is the best way to do it, and avoids this mess (as you've seen).
source to share