C++ Overloading within a class hierarchy


The following examples will use this class hierarchy:

struct A { int m; };
struct B : A {};
struct C : B {};

The conversion from derived class type to base class type is preferred to user-defined conversions. This applies when passing by value or by reference, as well as when converting pointer-to-derived to pointer-to-base.

struct Unrelated {
    Unrelated(B b);
void f(A a);
void f(Unrelated u);
B b;
f(b); // calls f(A)

A pointer conversion from derived class to base class is also better than conversion to void*.

void f(A* p);
void f(void* p);
B b;
f(&b); // calls f(A*)

If there are multiple overloads within the same chain of inheritance, the most derived base class overload is preferred. This is based on a similar principle as virtual dispatch: the "most specialized" implementation is chosen. However, overload resolution always occurs at compile time and will never implicitly down-cast.

void f(const A& a);
void f(const B& b);
C c;
f(c); // calls f(const B&)
B b;
A& r = b;
f(r); // calls f(const A&); the f(const B&) overload is not viable

For pointers to members, which are contravariant with respect to the class, a similar rule applies in the opposite direction: the least derived derived class is preferred.

void f(int B::*p);
void f(int C::*p);
int A::*p = &A::m;
f(p); // calls f(int B::*)