不同的编译器似乎对此主题有不同的看法。以下代码使用gcc
编译得很好,但是clang
失败了:
class Base {
protected:
static void f() {}
};
class Derived : public Base {
friend class DerivedFriend;
};
class DerivedFriend {
public:
void g() {
Base::f();
}
};
clang
的错误是:
main.cpp:13:15: error: 'f' is a protected member of 'Base'
Base::f();
^
main.cpp:3:17: note: declared protected here
static void f() {}
^
1 error generated.
答案 0 :(得分:2)
这是CWG issue 1873,它改变了这种情况的规则([class.access.base] / p5):
m
成员R
可在课程N
中点击m
- [...]
N
作为R
的成员受到保护,N
出现在班级P
的成员或朋友或成员中派生类来自N
的朋友m
,其中P
作为N
的成员是公共,私有或受保护的, 或- [...]
此处Base
为P
,Derived
为m
,f()
为R
,DerivedFriend
出现在f
的成员;在CWG1873之前,这是允许的,但CWG1873删除了派生类"的朋友。案件并使其形成不良。
此修复方法是将Derived
称为Base
的成员,而不是{{1}}。