C++ g++;4.5罐';找不到朋友函数
再见 在C++中,我有一个关于使用<代码>朋友< />的问题。考虑下面的代码: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&);
#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;
}