-1

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.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
a a
  • 322
  • 2
  • 9

1 Answers1

0

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I understand that, I just wanted to know how exactly the compiler knows that he checks classes for a name which are parallel in the inheritance hiarachy. – a a Nov 13 '22 at 12:25
  • 1
    The compiler knows the rules in the C++ standard, and simply follows the rules. The rules say, more or less: check all derived-from classes, and there must be exactly one match. The End. – Sam Varshavchik Nov 13 '22 at 12:26