假设访问控制出现在重载解决之前。实际上,这将意味着public/protected/private受控的可见性而不是可访问性。
Stroustrup 在 C++ 的设计和演变的第 2.10 节中有一段关于此的文章,他讨论了以下示例
int a; // global a
class X {
private:
int a; // member X::a
};
class XX : public X {
void f() { a = 1; } // which a?
};
Stroustrup 提到当前规则的一个好处(可访问性之前的可见性)是(暂时)将private内部更改class X为public(例如出于调试目的)是上述程序的含义没有安静的变化(即X::a试图在这两种情况下都可以访问,这在上面的示例中给出了访问错误)。如果public/protected/private将控制可见性,则程序的含义将改变(全局a将被调用private,否则X::a)。
然后他说他不记得这是通过显式设计还是预处理器技术的副作用,该技术用于使用标准 C++ 的前身 Classess 实现 C。
这与您的示例有什么关系?基本上是因为标准使重载解析符合名称查找在访问控制之前的一般规则。
10.2 成员名称查找[class.member.lookup]
1 成员名称查找确定类范围(3.3.7)中名称(id-expression)的含义。名称查找可能会导致歧义,在这种情况下程序格式错误。对于 id 表达式,名称查找从 this 的类范围开始;对于qualified-id,名称查找在nestedname-specifier 的范围内开始。名称查找发生在访问控制之前(3.4,第 11 条)。
8 如果明确找到重载函数的名称,则
重载决议(13.3)也发生在访问控制之前。歧义通常可以通过使用类名限定名称来解决。