【发布时间】:2019-06-27 16:57:47
【问题描述】:
在他最近的blog postAnthony Williams 中谈到了隐藏的朋友。如果我理解正确的话,主要思想是在某些情况下,ADL 无法找到声明为友元的函数。简单例子:
namespace N {
struct A {
friend void foo(A) { }
};
struct B {
operator A();
};
// (*)
void bar(A) { }
}
void func() {
N::A a;
bar(a); // OK, bar is found via ADL
foo(a); // OK, foo is found via ADL
N::B b;
bar(b); // OK, bar is found via ADL
foo(b); // NOT OK, foo cannot be found
}
在博文中的所有示例中,友元函数都是在类中定义的。是否可以声明一个友元函数,然后稍后在(*) 处定义它,以便它保持隐藏?看起来隐藏的朋友只能在类范围(或另一个编译单元)中定义。
【问题讨论】:
-
如你所说。它们必须在类范围内或在另一个编译单元中,因此您可以将它们放在源文件中,但是在该源文件中您无法享受隐藏朋友功能的好处,只有其他源文件可以。这就是为什么总是内联更好。整个技巧围绕着唯一可用的声明是在类范围内的声明,外部定义将是在类范围之外破坏效果的第二个声明。
-
如果你想隐藏一个隐藏朋友的实现,那么只需将它转发给一个私有成员函数,然后将那个实现放在你想要的任何地方。
标签: c++ friend argument-dependent-lookup