struct Base1
{
virtualvoid Foo( void )
{
std::cout << "Base1::Foo( void )\n";
}
virtualvoid Foo( int i )
{
std::cout << "Base1::Foo( int = " << i << " )\n";
}
};
struct Base2
: public Base1
{
virtualvoid Foo( int i )
{
std::cout << "Base2::Foo( int = " << i << " )\n";
}
};
template< class F >
struct CWrapper
: public F
{
virtualvoid Foo( void )
{
//ERROR - error: no matching function for call to `CWrapper<Base2>::Foo()'
F::Foo();
}
virtualvoid Foo( int i )
{
F::Foo( i );
}
};
Can anyone tell me if there is a good way to remove the above ERROR while only modifying CWrapper?
The virtual function call only works through pointers or references to the base class.
When accessed like a normal function (like the way you are attempting it) they behave just like normal functions.
Also templates and the virtual don't mix well.
You can do this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
template< class F >
struct CWrapper
: public F
{
virtualvoid Foo( void )
{
F::Base1::Foo();//see Note below
}
virtualvoid Foo( int i )
{
F::Foo( i );
}
};
Note:
What I have shown above will only work with the specific example you have posted - CWrapper<Base2> because F::Base1::Foo(); will expand to Base2::Base1::foo().
It wouldn't work with CWrapper<Base1> because F::Base1::Foo(); will expand to Base1::Base1::foo() which is again an error
Right now I can't think of a sensible way to make what you are trying to achieve work.
This is the way I was thinking though:
Thanks for the response. I had forgotten about the sub class syntax you pointed out
<class>::<baseclass>::<function>()
I didn't go into too much detail about the situation, but your above solution won't work for me, because I need to pass a pointer of type Base1 to an external system, that uses the virtual interface to call my implementation. The thing that I don't understand is that the below code compiles fine.
As I hinted in my original post - there is no polymorphism at work here - you are calling the virtual functions
directly e.g F::foo() - this means that they behave like normal functions.
There is something called 'data hiding' - which is basically as follows:
'If a derived class has a function with the same name as one in the base class, the function in the derived class hides ALL the functions in the base class with that name'
Which is why in your original post when when the template parameter F was a Base2 type - we could not
call F::Foo() - because it is hidden by Base2::Foo(int).
We got around this by saying F::Base1::Foo()
Thank you for the responses. This was exactly what I was looking for. I did understand that Polymorphism was not applied to the call (in fact I was counting on it), but I wasn't fully aware of the 'data hiding' mechanism. I'm not sure I'm clear WHY Foo( void ) hides Foo( int ) (or the other way around), but at least I know that this is an understood thing. I knew that there was some syntax for adding the function signature into the namespace of the deriving class, but couldn't remember it. While it doesn't solve my problem, I feel like at least I have enough information to work around the problem. Thanks again