I've got a situation where it seems like the compiler isn't finding the base class definition/implementation of a virtual function with the same name as another member function.
struct One {};
struct Two {};
struct Base
{
virtual void func( One & );
virtual void func( Two & ) = 0;
};
struct Derived : public Base
{
virtual void func( Two & );
};
void Base::func( One & )
{}
void Derived::func( Two & )
{}
// elsewhere
void this_fails_to_compile()
{
One one;
Derived d;
d.func( one );
}
I'm using Visual C++ 2008. The error message is:
error C2664: 'Derived::func' : cannot convert parameter 1 from 'One' to 'Two &'
I would have thought that the type based dispatch would work and call the defined base class function. If I add a Derived::func( One & )
it does compile and get called correctly, but in my situation, that version of the function can be done in the base class and usually derived classes don't need to implement it themselves. I'm currently working around it by putting a differently named, non-virtual function in the base class that forwards the call to function causing the problem:
// not virtual, although I don't think that matters
void Base::work_around( One & one )
{
func( one );
}
That works but is obviously less than ideal.
What inheritance and/or name-hiding rule am I missing here?
You hide
func(One&)
function inDerived
. You could use fully qualified name:You are hiding the method in the derived class. The simplest solution is to add a using declaration to the derived class.
The issue is that when the compiler tries to lookup the
func
identifier in the calld.func(one)
it has to do that fromDerived
upwards, but it will stop in the first context where it finds thefunc
identifier, which in this case it isDerived::func
. No further lookup is performed and the compiler was seeing only theDerived::func( Two& )
.By adding the
using Base::func;
directive, when the compiler sees theDerived
definition it brings all ofBase::func
declarations into scope, and it will find that there is aBase::func( One & )
that was not overridden inDerived
.Note also that if you were calling through a reference to
Base
, then the compiler would find both overloads offunc
and would dispatch appropriately each one to the final overrider.