gpt4 book ai didi

c++ - 同名友元函数和方法

转载 作者:行者123 更新时间:2023-11-27 22:35:21 25 4
gpt4 key购买 nike

以下类定义声明了一个友元函数,为其提供内联定义。我试图从一个与友元函数同名的类方法中调用友元函数,但为了让它工作,我必须从封闭的命名空间访问它(这也需要一个前向声明,class C 下面)。为什么名称查找适用于类 A 而在类 B 中不起作用?请注意,B::swap 的参数与其友元函数的参数不同。

#include <utility>

struct A {
A(int x) : v{ x } {}
friend void swap(A& x, A& y) { std::swap(x.v, y.v); }
void swapm(A& other) { swap(*this, other); }
private:
int v;
};

struct B {
B(int x) : v{ x } {}
friend void swap(B& x, B& y) { std::swap(x.v, y.v); }
void swap(B& other) { swap(*this, other); } // <-- This doesn't compile
private:
int v;
};

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

int main()
{
A a1{ 1 }, a2{ 2 }; swap(a1, a2); a1.swapm(a2);
B b1{ 3 }, b2{ 4 }; swap(b1, b2); b1.swap(b2);
C c1{ 5 }, c2{ 6 }; swap(c1, c2); c1.swap(c2);
}

最佳答案

不管这是个好主意,下面是对失败原因的解释:

编译器使用几个不同的处理阶段来弄清楚你的程序说了什么。类的原因B不编译是因为发生的故障发生在 friend 之前会被注意到。让我解释一下:

当编译器到达它试图弄清楚 swap 是什么的地步时意思是,它进行名称查找。它使用特定的规则来指定应该查看的位置。这是简化的,但基本上它首先查找在局部范围内定义的符号,然后在类范围内,然后在封闭(命名空间等)范围内。它找到在类范围内定义的那个,然后停止查找。那swap不采用这 2 个参数,因此编译失败。

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

在类里面A ,您正在使用不同的名称。在找到您的免费​​ swap 之前,名称查找阶段不会成功。功能。在类里面C ,您已经给出了名称查找的具体说明,“嘿,当您查找 swap 时,请查看全局命名空间范围,并忽略您可能会在本地和类范围内找到的那些。”

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

关于c++ - 同名友元函数和方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55101600/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com