一些友元函数不遵守规则
some friend functions don't follow the rule
对于以下片段:
class A{
friend void f(){};
public:
A(){f();} //error
};
class B{
friend void f(void* ptr){};
public:
B(){f(this);} //no error
};
根据规则,虽然可以在 class 中 定义 友元函数,但在 声明之前它们是不可见的 在 class 范围之外的某处,解释了 class A 定义中的错误。
但我很困惑,为什么 class B 的片段不会产生与 class A 相同的错误。
谁能告诉我这件事吗?
"Not visible" 有点过于简单化了。仅使用 in-class 定义,无法通过合格或不合格查找找到友元函数,这就是第一个代码片段失败的原因。
但是,它可以通过 参数相关查找 (ADL) 找到,因此您可以使用涉及与函数在同一命名空间范围内的类型的参数来调用它.
在这种情况下,参数类型是 B*
,范围在全局命名空间中。 friend 函数的范围在包含声明它的 class 的命名空间中 - 也是全局命名空间。因此 ADL 将在全局命名空间中查找名为 f
的函数,找到友元函数并使用它。
对于以下片段:
class A{
friend void f(){};
public:
A(){f();} //error
};
class B{
friend void f(void* ptr){};
public:
B(){f(this);} //no error
};
根据规则,虽然可以在 class 中 定义 友元函数,但在 声明之前它们是不可见的 在 class 范围之外的某处,解释了 class A 定义中的错误。
但我很困惑,为什么 class B 的片段不会产生与 class A 相同的错误。
谁能告诉我这件事吗?
"Not visible" 有点过于简单化了。仅使用 in-class 定义,无法通过合格或不合格查找找到友元函数,这就是第一个代码片段失败的原因。
但是,它可以通过 参数相关查找 (ADL) 找到,因此您可以使用涉及与函数在同一命名空间范围内的类型的参数来调用它.
在这种情况下,参数类型是 B*
,范围在全局命名空间中。 friend 函数的范围在包含声明它的 class 的命名空间中 - 也是全局命名空间。因此 ADL 将在全局命名空间中查找名为 f
的函数,找到友元函数并使用它。