Consider this code:
struct A
{
void foo() const
{
std::cout << \"const\" << std::endl;
}
private:
void foo()
This comes down to a fairly basic design decision in C++.
When looking up the function to satisfy a call, the compiler carries out a search like this:
It searches to find the first1 scope at which there's something with that name.
The compiler finds all the functions (or functors, etc.) with that name in that scope.
Then the compiler does overload resolution to find the best candidate among those it found (whether they're accessible or not).
Finally, the compiler checks whether that chosen function is accessible.
Because of that ordering, yes, it's possible that the compiler will choose an overload that's not accessible, even though there's another overload that's accessible (but not chosen during overload resolution).
As to whether it would be possible to do things differently: yes, it's undoubtedly possible. It would definitely lead to quite a different language than C++ though. It turns out that a lot of seemingly rather minor decisions can have ramifications that affect a lot more than might be initially obvious.