g++ 4.5 can't find a friend function

笑着哭i 提交于 2019-12-01 22:12:15

You have to declare the operators outside the struct as well. Same error is reported by gcc 4.4.

#include <ostream>

struct F {
};

struct N {
  friend std::ostream& operator<< (std::ostream&, const N&);
  friend std::ostream& operator<< (std::ostream&, const F&);    
};

std::ostream& operator<< (std::ostream&, const N&);
std::ostream& operator<< (std::ostream&, const F&);    

void foo(std::ostream &out) {
  F bar;
  out << bar;
}

The problem is that a friend declaration doesn't provide a global function declaration, unless you provide an inline implementation.

struct N {
   friend void func1() { }
   friend void func2();
   friend void func3();
};

void func3();

func1(); /* OK */
func2(); /* not OK */
func3(); /* OK */

I've been trudging through the standard (FCD, n3242) since I saw the question

In [class.friend] one can read:

6) A function can be defined in a friend declaration of a class if and only if the class is a non-local class (9.8), the function name is unqualified, and the function has namespace scope.

7) Such a function is implicitly inline. 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 the class is not (3.4.1).

9) A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.

So, what happens here ?

struct F {
};

struct N {
  friend std::ostream& operator<< (std::ostream&, const F&);    
};

The friend declaration nominates this overload of operator<< to be a friend of N. However this overload has not been declared in a lexical scope (either namespace or class). Also, 7 does not apply because it is not defined within N either.

Therefore, when looking up the overloads of operator<< that can apply in:

void foo(std::ostream &out) {
  F bar;
  out << bar;
}

There is no valid overload (actually, it could be there is no overload at all).

You have two solutions:

  • use 7: define the function inline following the friend declaration.
  • use 9: declare the function in the namespace too

Because of 4 though:

4) A function first declared in a friend declaration has external linkage (3.5). Otherwise, the function retains its previous linkage (7.1.1).

I would recommend declaring it prior to the friend declaration to control its linkage, but it will rarely matters.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!