Weird behaviour with templates, virtual inheritance and overloadedmethods

Discussion in 'C++' started by Lars Hillebrand, Nov 7, 2007.

  1. 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
     
    Lars Hillebrand, Nov 7, 2007
    #1
    1. Advertising

  2. Lars Hillebrand

    Duane Hebert Guest

    Re: Weird behaviour with templates, virtual inheritance and overloaded methods

    > 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.
     
    Duane Hebert, Nov 7, 2007
    #2
    1. Advertising

  3. Duane Hebert a écrit :
    >> 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.


    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
     
    Michael DOUBEZ, Nov 7, 2007
    #3
  4. Lars Hillebrand wrote:
    > 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.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Nov 7, 2007
    #4
  5. Lars Hillebrand

    Duane Hebert Guest

    Re: Weird behaviour with templates, virtual inheritance and overloaded methods

    "Michael DOUBEZ" <> wrote in message
    news:4731b5af$0$15440$...
    > Duane Hebert a écrit :
    >>> 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.

    >
    > 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.
     
    Duane Hebert, Nov 7, 2007
    #5
  6. Hello again,

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

    using TypedInterfaceImplementation<T>::TestFunction;

    it works!

    Lars
     
    Lars Hillebrand, Nov 8, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    3
    Views:
    492
  2. recover
    Replies:
    2
    Views:
    830
    recover
    Jul 25, 2006
  3. Ashwin
    Replies:
    2
    Views:
    356
    Pierre Barbier de Reuille
    Aug 1, 2006
  4. Student
    Replies:
    11
    Views:
    462
    James Kanze
    Dec 6, 2010
  5. cesarth
    Replies:
    2
    Views:
    226
    Victor Bazarov
    Oct 28, 2011
Loading...

Share This Page