访问类中定义的朋友函数

有这样的代码:

#include <iostream> class A{ public: friend void fun(A a){std::cout << "Im here" << std::endl;} friend void fun2(){ std::cout << "Im here2" << std::endl; } friend void fun3(); }; void fun3(){ std::cout << "Im here3" << std::endl; } int main() { fun(A()); // works ok //fun2(); error: 'fun2' was not declared in this scope //A::fun2(); error: 'fun2' is not a member of 'A' fun3(); // works ok } 

如何访问函数fun2()?

 class A{ public: friend void fun(A a){std::cout << "Im here" << std::endl;} friend void fun2(){ std::cout << "Im here2" << std::endl; } friend void fun3(); }; 

尽pipefun2定义确实定义了一个“全局”函数而不是一个成员,并且同时使它成为A一个friendA在全局范围本身中仍然缺less相同函数的声明。

这意味着该范围中的任何代码都不存在fun2存在的任何想法。

同样的问题发生的fun ,除了参数依赖查找可以接pipe并find函数,因为有一个typesA的参数。

我build议用通常的方式来定义你的function:

 class A { friend void fun(A a); friend void fun2(); friend void fun3(); }; void fun(A a) { std::cout << "I'm here" << std::endl; } void fun2() { std::cout << "I'm here2" << std::endl; } void fun3(); 

现在注意, 一切正常 ( fun3除外,因为我从来没有定义过)。

你可以调用fun的原因是, A类中的朋友声明只能通过依赖于参数的查找来使其可见。 否则,朋友声明不会使它们声明的函数在出现的类范围之外自动可见。

您需要在命名空间范围或main内添加一个声明,以使fun2main可见。

例如

 void fun2(); 

fun3main里面是可见的,因为它的定义(在类之外)也是一个声明,使得它可以从main看到。

ISO / IEC 14882:2011 7.3.1.2:

直到在该名称空间范围内(在授予友谊的类定义之前或之后)提供匹配声明之前,通过无限制查找(3.4.1)或合格查找(3.4.3)才能find该朋友的名字。

3.4.2(与参数相关的名称查找)/ 4:

任何在关联类中声明的名称空间范围的好友函数或好友函数模板,在其各自的名称空间内都是可见的,即使它们在普通查找过程中不可见(11.3)。