C++ g++;4.5罐';找不到朋友函数

C++ g++;4.5罐';找不到朋友函数,c++,g++,friend,C++,G++,Friend,再见 在C++中,我有一个关于使用朋友< />的问题。考虑下面的代码: #include <ostream> struct F { }; struct N { friend std::ostream& operator<< (std::ostream&, const N&); friend std::ostream& operator<< (std::ostream&, const F&);

再见

在C++中,我有一个关于使用<代码>朋友< />的问题。考虑下面的代码:

#include <ostream>

struct F {
};

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

void foo(std::ostream &out) {
  F bar;
  out << bar;
}
是g++4.5错了还是我(和g++4.0)错了


(将友元声明移动到
F
类中的解决方案没有帮助,因为
操作符问题在于友元声明不提供全局函数声明,除非提供内联实现

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

void func3();

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

您还必须在结构外部声明运算符。GCC4.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;
}
#包括
结构F{
};
结构{

friend std::ostream&operator自从我看到这个问题以来,我一直在艰难地通过标准(FCD,n3242)

[class.friend]中,可以阅读:

6) 当且仅当类是非本地类(9.8)、函数名不合格且函数具有命名空间范围时,才能在类的友元声明中定义函数

7) 这样的函数是隐式内联的。在类中定义的友元函数在定义它的类的(词法)范围内。在类之外定义的友元函数不在(3.4.1)范围内

9) 友元声明指定的名称应可在包含友元声明的类的范围内访问

那么,这里发生了什么

struct F {
};

struct N {
  friend std::ostream& operator<< (std::ostream&, const F&);    
};
没有有效的重载(实际上,可能根本没有重载)

您有两种解决方案:

  • 使用
    7
    :在友元声明之后内联定义函数
  • 使用
    9
    :也在名称空间中声明函数
由于
4
尽管:

4) 首先在友元声明中声明的函数具有外部链接(3.5)。否则,该函数将保留其先前的链接(7.1.1)


我建议在
friend
声明之前声明它,以控制其链接,但这几乎不重要。

您是否尝试过在名称空间中正确声明运算符?我认为这是一个名称查找问题。实际上,类
N
F
最初位于名称空间
xml
中,而且时间较晚r我通过
使用命名空间xml
导入了整个命名空间。这没有什么区别!正如Let_Me_Be所指出的,问题是将声明锚定到上下文中的问题。
friend
不会锚定声明,除非您立即定义函数。如果函数名仅由“friend”声明引入n然后只能通过依赖于参数的查找(ISO 3.4.2)找到它。有很多规则,但在这里的示例中,任何“运算符”都最喜欢您的答案,但我想它太简洁,无法选择:/friend是否是定义并不相关。如果只声明(或定义)函数作为朋友,则不会在命名空间中显式命名。它可能通过依赖参数的查找找到,但这不适用于您的示例,因为函数上没有参数。定义朋友对名称的可见性没有影响。上面的项目符号7指的是如何解析朋友函数的定义例如,如果
TYPE
引用类外的
void
和类内的
int
,则类中定义的朋友将
TYPE
视为
int
,即使类中稍后声明了
TYPE
。类外定义的朋友需要一个限定的名称才能在类中查找
TYPE
类,即,它被解析为名称空间函数。
struct F {
};

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