Weird behaviour with templates, virtual inheritance and overloadedmethods

  • Thread starter Lars Hillebrand
  • Start date
L

Lars Hillebrand

Hello,
i discovered a weird behaviour if i use templates together with virtual
inheritance and method over. I managed to reproduce my problem with a
small example:

// *********** <code example> **********
template<typename T> class TypedInterface
{
public:
virtual void TestFunction( T * ) = 0;
};


template<typename T> class TypedInterfaceImplementation :
public TypedInterface<T>
{
public:
void TestFunction( T * ) { };
};


template<typename T> class Test :
public TypedInterfaceImplementation< T >
{
public:
void TestFunction( T , T ) { };
};


void testme()
{
Test< float > TestObject;

// Call to Test::TestFunction, OK:
TestObject.TestFunction( 1.0, 1.0 );

float fOne = 1.0;

// Call to TypedInterfaceImplementation::TestFunction results in an
error:
// error C2660: 'Test<T>::TestFunction': function does not take 1
parameters
TestObject.TestFunction( &fOne );
}
// *********** </code example> **********

The method 'TypedInterfaceImplementation::TestFunction' doesn't seem to
belong to the interface of class 'Test', but it should be available
because i only use public inheritance. The method
'Test<T>::TestFunction( T , T )' should just overload the virtual
method, not overwrite it!
If i rename 'Test<T>::TestFunction( T , T ) { };' so it is not
overloaded anymore, the error is gone. But i would realy like to
overload it.

Am i doing something wrong?

I'm using Visual Studio 2005 (i have to :-( ), Version 8.0.50727.42, no
service-pack.

Thanks in advance for all answers!

Lars
 
D

Duane Hebert

The method 'TypedInterfaceImplementation::TestFunction' doesn't seem to
belong to the interface of class 'Test', but it should be available
because i only use public inheritance. The method
'Test<T>::TestFunction( T , T )' should just overload the virtual method,
not overwrite it!
If i rename 'Test<T>::TestFunction( T , T ) { };' so it is not overloaded
anymore, the error is gone. But i would realy like to overload it.

Am i doing something wrong?

I'm not positive with templates, but without templates,
you would be hiding the base function, not overriding
or overloading it.

One way around it is to bring the base function into
scope with a using clause but I'm not sure how this
works with templates.
 
M

Michael DOUBEZ

Duane Hebert a écrit :
I'm not positive with templates, but without templates,
you would be hiding the base function, not overriding
or overloading it.

One way around it is to bring the base function into
scope with a using clause but I'm not sure how this
works with templates.

That way:

template<typename T> class Test :
public TypedInterfaceImplementation< T >
{
public:
void TestFunction( T , T ) { };
using TypedInterfaceImplementation<T>::TestFunction;
};

Otherwise, TypedInterfaceImplementation<T>::TestFunction(T*) never get
instanciated.

Michael
 
A

Andrey Tarasevich

Lars said:
i discovered a weird behaviour if i use templates together with virtual
inheritance and method over.

The behavior you "discovered" is called name hiding. It really has
nothing to do with templates, virtual inheritance and such. (And BTW
there's no virtual inheritance in your code.) A much simpler example
that demonstrates the same error could look as follows

struct A { void foo(int) {} };
struct B : A { void foo(int, int) {} };

int main() {
B b;
b.foo(5); // ERROR
}

Read the FAQ on name hiding to understand why it fails.
 
D

Duane Hebert

Michael DOUBEZ said:
Duane Hebert a écrit :

That way:

template<typename T> class Test :
public TypedInterfaceImplementation< T >
{
public:
void TestFunction( T , T ) { };
using TypedInterfaceImplementation<T>::TestFunction;
};

Otherwise, TypedInterfaceImplementation<T>::TestFunction(T*) never get
instanciated.

That's what I expected though I hadn't had a
chance to test it. It's just a case of "hiding" and
nothing to do with templates. Same would be true
of a straight class hierarchy.
 
L

Lars Hillebrand

Hello again,

thanks for all answers!
With a 'using' clause like this:

using TypedInterfaceImplementation<T>::TestFunction;

it works!

Lars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top