0

I would like some clarification as to the behavior of the following:

#include <iostream>

class A {};

class B : public A {};

class Q : public A {};

class C : public B {};

void doOverload(const A& v)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void doOverload(const B& v)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void doOverload(const C& v)
{
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}


int main()
{
    A a;
    B b;
    C c;
    Q q;
    
    doOverload(a);
    doOverload(b);
    doOverload(c);
    doOverload(q);
}

If I compile and run this using GCC on my PC, the output is:

void doOverload(const A&)
void doOverload(const B&)
void doOverload(const C&)
void doOverload(const A&)

Which means that, for example, even though type B "is a" A, the compiler chooses the override for the most specific type. Likewise, Q is also an A but no specific overloaded method exists for Q so the overload for A is chosen.

My question is, is this guaranteed by the standard? If yes, where in the standard?

Louen
  • 3,617
  • 1
  • 29
  • 49
Patrick Wright
  • 1,401
  • 7
  • 13
  • Think about it: How would you pass `b` as an `A`? – tadman Jan 17 '23 at 22:04
  • 7
    "No conversion" is a [better implicit conversion sequence](https://en.cppreference.com/w/cpp/language/overload_resolution#Ranking_of_implicit_conversion_sequences) than "derived to base conversion". So `B` to `B` is guaranteed to be considered better than `B` to `A`. – Nathan Pierson Jan 17 '23 at 22:06
  • 2
    Furthermore, assuming `Derived` inherits from `Mid` and `Mid` inherits from `Base`, `Derived` to `Mid` is also considered a better conversion than `Derived` to `Base`. So, for instance, if you didn't have the `const C&` overload, it would still be required by the standard that `doOverload(c)` chooses the `const B&` overload and not the `const A&` overload. – Nathan Pierson Jan 17 '23 at 22:11

0 Answers0