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?

+3


source to share


2 answers


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).

+5


source


I'm sure this is an approved standard. Here at university I visit whenever we used the friends function, it was always out of class. I'm not 100% sure why myself, but I know it works without causing problems.



0


source







All Articles