Reputation: 8713
In this thread the author of the accepted answer explains why the overridden method in the derived class can not be resolved by the compiler. However the example is relative to a type cast resolution, that is both the base and derived overloaded method have one parameter only and the ambiguity is limited to that parameter type.
But where is the ambiguity when the overloaded methods have a different number of parameters, like in this example?
Note that I'm not asking why the example produces a compile error, I'm asking why the language was designed this way.
#include <iostream>
using namespace std;
class A
{
public:
inline int f(int x) { return x; }
};
class B: public A
{
public:
inline int f(int x, int y) { return x+y; }
};
int main()
{
B b;
cout << b.f(1) << endl; // COMPILE ERROR
cout << b.f(1,2) << endl;
}
Upvotes: 5
Views: 116
Reputation: 780
How would you take away overloads that make no sense in a derived class? Even in your example, assume that if you have a B instance, you wanted to forbid the use of the single-parameter function. As it is written now, you've removed the single-parameter version (well, at least removed it from name resolution in the context of a B instance). But if you wanted to still have that version available, you can specify using A::F;
in your class to bring in the single-parameter version.
Upvotes: 0
Reputation: 361
In C++, name lookup will stop looking for other names as soon as it find the requested name in one of the base classes.
In your case, the name f
is defined in B
, so the compiler stop looking in the other base classes.
You can make A::f visible with a using declaration :
class B: public A
{
public:
using A::f;
int f(int x, int y) { return x+y; }
};
Upvotes: 1
Reputation: 10348
The reason you get a compiler error is that f
from class A
is hidden by the f
in class B
.
When the compiler does member name lookup, it uses base classes only if the name is not found in the object's class, so it doesn't matter if you have a member in a base class that has a proper parameter list for your call.
From the standard:
10.2.5 Otherwise (i.e., C does not contain a declaration of f or the resulting declaration set is empty), S(f, C) is initially empty. If C has base classes, calculate the lookup set for f in each direct base class subobject Bi , and merge each such lookup set S(f, Bi) in turn into S(f, C).
Upvotes: 1
Reputation: 35440
The compiler will look for the implementation of function f
in class B
. The compiler found such an implementation, which has two arguments. You provided only one argument, so there is your error.
Upvotes: 0