C++ Name lookup and access checking


Overload resolution occurs after name lookup. This means that a better-matching function will not be selected by overload resolution if it loses name lookup:

void f(int x);
struct S {
    void f(double x);
    void g() { f(42); } // calls S::f because global f is not visible here,
                        // even though it would be a better match

Overload resolution occurs before access checking. An inaccessible function might be selected by overload resolution if it is a better match than an accessible function.

class C {
    static void f(double x);
    static void f(int x);
C::f(42); // Error! Calls private C::f(int) even though public C::f(double) is viable.

Similarly, overload resolution happens without checking whether the resulting call is well-formed with regards to explicit:

struct X {
    explicit X(int );
    X(char );

void foo(X );
foo({4}); // X(int) is better much, but expression is 
          // ill-formed because selected constructor is explicit