12 Overloading [over]

12.3 Declaration matching [over.dcl]

Two function declarations of the same name refer to the same function if they are in the same scope and have equivalent parameter declarations ([over.load]) and equivalent ([temp.over.link]) trailing requires-clauses, if any ([dcl.decl]).
[Note
:
Since a constraint-expression is an unevaluated operand, equivalence compares the expressions without evaluating them.
[Example
:
template<int I> concept C = true;
template<typename T> struct A {
  void f() requires C<42>;      // #1
  void f() requires true;       // OK, different functions
};
— end example
]
— end note
]
A function member of a derived class is not in the same scope as a function member of the same name in a base class.
[Example
:
struct B {
  int f(int);
};

struct D : B {
  int f(const char*);
};
Here D​::​f(const char*) hides B​::​f(int) rather than overloading it.
void h(D* pd) {
  pd->f(1);                     // error:
                                // D​::​f(const char*) hides B​::​f(int)
  pd->B::f(1);                  // OK
  pd->f("Ben");                 // OK, calls D​::​f
}
— end example
]
A locally declared function is not in the same scope as a function in a containing scope.
[Example
:
void f(const char*);
void g() {
  extern void f(int);
  f("asdf");                    // error: f(int) hides f(const char*)
                                // so there is no f(const char*) in this scope
}

void caller () {
  extern void callee(int, int);
  {
    extern void callee(int);    // hides callee(int, int)
    callee(88, 99);             // error: only callee(int) in scope
  }
}
— end example
]
Different versions of an overloaded member function can be given different access rules.
[Example
:
class buffer {
private:
    char* p;
    int size;
protected:
    buffer(int s, char* store) { size = s; p = store; }
public:
    buffer(int s) { p = new char[size = s]; }
};
— end example
]