声明受保护的功能朋友

时间:2014-08-05 17:02:56

标签: c++ function friend protected

A::foo是否需要公开B才能宣布它为朋友?

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认为它不是并且希望它是公开的。哪个编译器正确?我最初的直觉是它可以被宣布为受保护。毕竟,B是从A派生的,所以应该可以访问A :: foo(因为B :: goo很简单地演示)。

1 个答案:

答案 0 :(得分:2)

VS在这里是正确的

A::foo名称B实际上可以在A范围内访问,因为它来自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) {} 。要prove这个,请考虑

foo

所以使用引用§11.3[朋友功能]

  

朋友声明提名的名称应在包含朋友声明的类的范围内访问。

我们可以争辩说,没有违反规则(friend在派生类中也受到保护)。

好像在gcc中,一旦将{{1}}关键字放在友元函数声明的前面,名称查找就会开始忽略继承(虽然友谊不可继承,但无所事事)


正如40two在评论中提到的那样,Clang发出了相同的错误,并且bug report;此问题也适用于DR209。似乎对于实施者来说,做到这一点非常困难。