I thought I understood inheritance, and virtual functions, and function overloading, but I've got a case where something about the interplay between these features is eluding me.
Suppose I've got a simple base class containing an overloaded virtual function, and a second class derived from it:
class b {
public:
virtual int f() { return 1; }
virtual int f(int) { return 2; }
};
class d : public b {
public:
virtual int f(int) { return 3; }
};
Notice that the derived class d
overrides only one of the overloaded virtual functions.
I can instantiate an object of class d
and invoke f(int)
on it, no problem:
d x;
std::cout << x.f(0) << std::endl;
But when I try to call the 0-argument function:
std::cout << x.f() << std::endl;
it fails! gcc says "no matching function for call to 'd::f()'; candidates are: virtual int d::f(int)". clang says "too few arguments to function call, expected 1, have 0; did you mean 'b::f'?" Even though d
is derived from b
which has a 0-argument f()
method, the compiler is ignoring that, and trying to call d
's 1-argument method instead.
I can fix this by repeating the definition of the 0-argument function in the derived class:
class d : public b {
public:
virtual int f() { return 1; }
virtual int f(int) { return 3; }
};
Or, as suggested by clang's error message, I can use a goofy disambiguation syntax that I never would have guessed would work:
std::cout << x.b::f() << std::endl;
But my question is, what rule did I break, and what is that rule trying to enforce/protect/defend? What I thought I was trying to do here was exactly the sort of thing I thought inheritance was for.