Cuando llama a.foo();
, el compilador pasa por la resolución de sobrecarga para encontrar la mejor función para usar. Cuando construye el conjunto de sobrecarga, encuentra
void foo() const
y
void foo()
Ahora, dado a
que no lo es const
, la versión no constante es la mejor coincidencia, por lo que el compilador elige void foo()
. Luego, se establecen las restricciones de acceso y se obtiene un error del compilador, ya que void foo()
es privado.
Recuerde, en la resolución de sobrecarga no es "encontrar la mejor función utilizable". Es "encontrar la mejor función e intentar usarla". Si no puede debido a restricciones de acceso o si se está eliminando, aparece un error del compilador.
En otras palabras, ¿por qué la resolución de sobrecarga viene antes que el control de acceso?
Bueno, veamos:
struct Base
{
void foo() { std::cout << "Base\n"; }
};
struct Derived : Base
{
void foo() { std::cout << "Derived\n"; }
};
struct Foo
{
void foo(Base * b) { b->foo(); }
private:
void foo(Derived * d) { d->foo(); }
};
int main()
{
Derived d;
Foo f;
f.foo(&d);
}
Ahora digamos que en realidad no quise hacerlo void foo(Derived * d)
privado. Si el control de acceso fuera lo primero, este programa se compilaría, se ejecutaría y Base
se imprimiría. Esto podría ser muy difícil de rastrear en una base de código grande. Dado que el control de acceso viene después de la resolución de sobrecarga, obtengo un buen error del compilador que me dice que no se puede llamar a la función que quiero que llame, y puedo encontrar el error mucho más fácilmente.