A::foo
是否需要为 B
声明为 public 以将其声明为 friend?
class A {
protected: // public ?
void foo(int x);
};
class B : public A {
friend void A::foo(int); // not fine with GCC 4.8.1 but fine with VS 2013
void goo(int x) {foo(x);} // fine
static void hoo(int x) {}
};
void A::foo(int x) {B::hoo(x);} // friend declaration needed for this
Visual Studio 2013 认为如果 A::foo 受到保护就没问题,但 GCC 4.8.1 认为它不 protected 并希望它公开。哪个编译器是正确的?我最初的直觉是它可以被宣布为 protected 。毕竟,B 派生自 A,因此应该可以访问 A::foo(正如 B::goo 所简单演示的那样)。
最佳答案
这里 VS 是正确的。
名称 A::foo
实际上在 B
的范围内是可访问的,因为它是从 A
公开派生的。至prove这个,考虑一下
class A {
protected:
void foo(int x);
};
class B : A {
using A::foo; // it's OK to refer to the name A::foo
};
void A::foo(int x) {}
所以通过引用 § 11.3 [友元函数]
A name nominated by a friend declaration shall be accessible in the scope of the class containing the friend declaration.
我们可以争辩说没有违反规则(foo
在派生类中也受到保护)。
似乎在 gcc 中,一旦将 friend
关键字放在 friend 函数声明的前面,名称查找就开始忽略继承(尽管与不可继承的友元无关)
如 40two 所述在评论中 Clang 发出了同样的错误并且有一个 bug report为它;这个问题也提到了DR209 .对于实现者来说,似乎很难做到这一点。
关于c++ - 声明 protected 功能 friend ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25144439/