C++ 在非ST对象上,为什么赢了';tc++;调用具有public const和private nonconst重载的方法的const版本?

C++ 在非ST对象上,为什么赢了';tc++;调用具有public const和private nonconst重载的方法的const版本?,c++,overload-resolution,private-methods,public-method,const-method,C++,Overload Resolution,Private Methods,Public Method,Const Method,MSVC 2013不喜欢这样: class C { public: void foo() const {} private: void foo() {} }; int main() { C c; c.foo(); } 如果我强制转换到const引用,它会起作用: > error C2248: 'C::foo' : cannot access private member declared in class 'C' const_cast(c.foo();

MSVC 2013不喜欢这样:

class C
{
public:
    void foo() const {}
private:
    void foo() {}
};

int main()
{
    C c;
    c.foo();
}
如果我强制转换到
const
引用,它会起作用:

> error C2248: 'C::foo' : cannot access private member declared in class 'C'
const_cast(c.foo();

为什么我不能在非
const
对象上调用
const
方法?

该对象不是
const
,因此非
const
重载是更好的匹配。重载解析发生在访问检查之前。这确保了过载分辨率不会因更改成员函数的访问权限而意外更改。

标准:

13.3.3如果存在最佳可行函数且该函数是唯一的,则重载解析成功并产生结果。 否则重载解析将失败,并且调用的格式不正确重载解析成功时,以及 最佳可行函数是不可访问的(第11条),在使用它的上下文中,程序是 格式不正确。


其原因是,设计人员认为查找和解析依赖于访问检查很容易出错;将一个方法从public更改为private可能会导致该函数的使用在没有意图的情况下悄悄地切换到其他函数。C++中的查找语义应用于访问检查不存在的情况。然后应用访问检查。访问检查不影响可见性和选择,只影响权限。因此,类外部的代码可以通过添加私有成员函数来中断。外部代码依赖于类内部。@usr,但会出现编译器错误。如果不是这样,当您更改成员函数的访问权限时,代码的行为可能会悄无声息地更改。@juanchopanza导致编译器错误是一种破坏性的更改。如果C在库中,则该库必须仔细命名其私有成员,以免在库更新时导致依赖代码中断。@usr更改行为也是一个中断性更改。最好早点失败。但在实际代码中,不应该有具有不同访问权限的重载。
const_cast<C const &>(c).foo();