c++overloadingmultiple-inheritancename-lookup

How does Name lookup work when using multiple inheritance in C++?


Why does the following work(I know it would not work when d.f(5)):

#include <string>
#include <iostream>

struct A { int f(int a) { return a*a; } };
struct B : A { std::string f(std::string string) { return "Hello " + string; } };
struct Derived : B {};

int main()
{
   Derived d;
   std::cout << d.f("5") << std::endl;

   return 0;
}

and the following doesnt:

#include <string>
#include <iostream>

struct A { int f(int a) { return a*a; } };
struct B { std::string f(std::string string) { return "Hello " + string; } };
struct Derived : B, A {};

int main()
{
   Derived d;
   std::cout << d.f("5") << std::endl;

   return 0;
}

You could make the last example work by adding:

using A::f;
using B::f;

in Derived, but shouldnt the compiler just check either A or B which would be the same case as in the first example?

Edit:
Here is the error message:

main.cpp: In function ‘int main()’:
main.cpp:11:19: error: request for member ‘f’ is ambiguous
   11 |    std::cout << d.f("5") << std::endl;
      |                   ^
main.cpp:4:16: note: candidates are: ‘int A::f(int)’
    4 | struct A { int f(int a) { return a*a; } };
      |                ^
main.cpp:5:24: note:                 ‘std::string B::f(std::string)’
    5 | struct B { std::string f(std::string string) { return "Hello " + string; } };
      |                        ^

Edit 2: I think I phrased my question wrong, the question was more about the how exactly the compiler differentiates between multiple inheritance and single inharitance when perfoming name lookup.

Edit 3: I got it now, thanks.


Solution

  • In the former case the class does not have a method whose name matches the method name getting called. Next, the class is derived from a class, and the derived-from class has a method with the matching name, which satisfies the name getting looked up.

    In the latter case the class is derived from two other classes, and both of them have a method with the matching name. The name lookup is now ambiguous.

    but shouldnt the compiler just check either A or B

    It is not up to the compiler to decide this. This rules for name lookups are specified in the C++ standard, and the compiler must follow the name lookup rules.