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 1:
Since a constraint-expression is an unevaluated operand, equivalence compares the expressions without evaluating them.
[Example 1: 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 2: 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 3: 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 4: 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]