【发布时间】:2023-03-07 07:09:01
【问题描述】:
[class.access/1] 中的 C++ 标准状态(强调我的):
一个类的成员可以是
- 私人;也就是说,它的名称只能被声明它的类的成员和朋友使用。
- 受保护;也就是说,它的名称只能由声明它的类的成员和朋友、从该类派生的类、及其朋友使用(参见 [class.protected])。
- 公开;也就是说,它的名称可以在任何地方使用而不受访问限制。
那么为什么编译器会在下面的 C++ 程序中引发这个错误呢?
#include <iostream>
class B {
protected:
static int const i = 1;
};
class D: public B {
public:
void f();
friend void g();
};
void D::f() {
B b;
std::cout << b.i; // OK
}
void g() {
B b;
std::cout << b.i; // error: 'i' is a protected member of 'B'
}
int main() {
D d;
d.f();
g();
return 0;
}
请注意,受保护的数据成员 B::i 被声明为 static 不受 [class.access/class.protected-1] 中受保护的非静态成员的进一步限制,这将在D::f 成员函数中的b.i 访问也会引发与g 函数中相同的错误。
注意。 — 我在 Clang 9.0.0 编译器上使用 C++ 17。
【问题讨论】:
-
仅供参考失败; g++ 和 MSVC 编译 - 实时:godbolt.org/z/TkmnbW 您可能需要添加 [language-lawyer] 标签
-
另外,如果你定义
g内联(并稍微修改它以便可以通过 ADL 调用)然后 clang 也会编译:godbolt.org/z/_2rEdA 对我来说似乎是一个 clang 错误。
标签: c++ language-lawyer friend protected derived-class