具有相同名称的Friend函数和方法

时间:2019-03-11 12:11:16

标签: c++ friend

以下类定义声明了一个朋友函数,该函数为其提供了内联定义。我试图从具有与朋友功能相同名称的类方法中调用朋友功能,但是为了使其起作用,我必须从封闭的名称空间(也需要一个前向声明,类{{1})中访问它。 })。为什么名称查找可用于类C而不能在类A中工作?请注意,B的参数与其朋友函数的参数不同。

B::swap

2 个答案:

答案 0 :(得分:4)

这是一个好主意,以下是其失败原因的解释:

编译器使用几个不同的处理阶段来确定您的程序说什么。类B之所以不能编译,是因为发生的故障发生在friend被注意到之前。让我解释一下:

当编译器试图找出swap的含义时,它将进行名称查找。它使用特定的规则来指定外观。这是经过简化的,但是基本上,它首先查找在局部范围内定义的符号,然后在类范围内,然后在封闭(名称空间等)范围内。它找到在类范围内定义的那个,并停止查找。 swap不使用这两个参数,因此编译失败。

friend声明允许您使用自由函数访问B的内部结构,它是您在全局命名空间中声明的swap函数的附加声明。如果编译器在名称查找中考虑了全局命名空间中的函数,则将考虑这些声明。在类B中,编译器在进入此阶段之前已经停止了处理。 (而且,friend声明在以后的阶段中是必需的,因为编译器正在编译与swap对象一起使用的B函数的版本,并想弄清楚,“在名为swap的函数中,它可以接受这两个参数;我可以访问B的内部信息吗?”)

A类中,您使用了另一个名称。直到找到免费的swap函数,名称查找阶段才会成功。在类C中,您提供了有关名称查找的特定说明,“嘿,当您查找swap时,请查看全局命名空间范围,而忽略本地和类中的​​名称-您可能会发现的范围。”

(注意:@PeteBecker发表评论后,名称查找和friend的描述已更新。)

答案 1 :(得分:0)

inline friend?在这种情况下为什么不static呢?而不是friend吗?然后创建一个称为static的全局变量。对我来说,这是一个糟糕的设计,而不是实际的问题。

方法swap应该是工作方法,而不是friend(因为不再需要朋友了):

struct C {
    C(int x) : v{ x } {}
    void swap(C& other) { std::swap(this->v, other.v); }
private:
    int v;
};

void swap(C& x, C& y)
{
  x.swap(y);    
}