在[class.access/1]中,C++标准规定(强调我的):
一个类的成员可以是:
- private:只有在该类中声明的成员和友元才能使用它的名称。 - protected:只有在该类中声明的成员和友元,以及从该类派生的类和它们的友元(见[class.protected])才能使用它的名称。 - public:即其名称可在任何地方使用,没有访问限制。
那么为什么编译器会在以下C++程序中引发此错误呢?
请注意,受保护的数据成员
一个类的成员可以是:
- private:只有在该类中声明的成员和友元才能使用它的名称。 - protected:只有在该类中声明的成员和友元,以及从该类派生的类和它们的友元(见[class.protected])才能使用它的名称。 - public:即其名称可在任何地方使用,没有访问限制。
那么为什么编译器会在以下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
被声明为静态,以免受到特定于受保护的非静态成员的进一步限制,在[class.access/class.protected-1]中也会在D::f
成员函数和g
函数中的b.i
访问处引发相同的错误。
注意。 — 我正在使用Clang 9.0.0编译器上的C++ 17。
g
(并稍微修改它以便通过 ADL 调用),那么 clang 也会编译:https://godbolt.org/z/_2rEdA 对我来说看起来像是一个 clang 的 bug。 - N. Shead