Consider this code:
struct A
{
void foo() const
{
std::cout << "const" << std::endl;
}
private:
void foo()
{
std::cout << "non - const" << std::endl;
}
};
int main()
{
A a;
a.foo();
}
The compiler error is:
error: 'void A::foo()' is private`.
But when I delete the private one it just works. Why is the public const member function not called when the non-const one is private?
In other words, why does overload resolution come before access control? This is strange. Do you think it is consistent? My code works and then I add a member function, and my working code does not compile at all.
Best Answer
When you call
a.foo();
, the compiler goes through overload resolution to find the best function to use. When it builds the overload set it findsand
Now, since
a
is notconst
, the non-const version is the best match, so the compiler picksvoid foo()
. Then the access restrictions are put in place and you get a compiler error, sincevoid foo()
is private.Remember, in overload resolution it is not 'find the best usable function'. It is 'find the best function and try to use it'. If it can't because of access restrictions or being deleted, then you get a compiler error.
Well, let's look at:
Now let's say that I did not actually mean to make
void foo(Derived * d)
private. If access control came first then this program would compile and run andBase
would be printed. This could be very hard to track down in a large code base. Since access control comes after overload resolution I get a nice compiler error telling me the function I want it to call cannot be called, and I can find the bug a lot easier.