CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18

Hybrid View

  1. #1
    Join Date
    Sep 2005
    Posts
    11

    [RESOLVED] overwrite virtual template methods

    Hi Folks,
    I've got a template and the relevant code looks like this:
    ----
    public:
    virtual bool IsValid () const
    {
    return IsValid (mMemberValue);
    }

    protected:
    virtual bool IsValid (int value)const
    {
    //Here ist a little code testing value.
    }
    ----

    IsValid() does no more than calling IsValid(int).
    If I try now to overwrite IsValid(), the compiler complains, that my new IsValid() hides IsValid(int).
    If I try to overwrite IsValid(int), it complains about hiding IsValid().

    As we're using Borland C++ 6, I know I could make the compiler stop complaining by using HIDESBASE.
    But this - IMHO - strange warning makes me a little bit nervous. I think the compiler should be able to differ both methods by signature - as it does with methods in "real" classes.
    Or am I seeing sth. wrong?

    Thanks in advance
    chabba

  2. #2
    Join Date
    Jan 2006
    Location
    Belo Horizonte, Brazil
    Posts
    405

    Re: overwrite virtual template methods

    I cannot say that for sure because you didn't post all the code.

    The hidding situation is in accordance to the standard. This happens even for non-templates classes. The C++ lookup mechanism will not look further for in other scopes if it already finds a name match in the current class. Example:

    Code:
    struct A
    {
      bool IsValid(int i) const {return true;}
    };
    
    struct B : A
    {
      bool IsValid(int x, int y) const {return true;} 
    
      //Uncomment below to fix.
      //using A::IsValid; 
    };
    
    int main()
    {
      B b;
      int i = 10;
      bool x = b.IsValid(i); //Error, only IsValid(int, int) from B is visible.
      
      /* ... */
    }
    One way to fix it is with a using directive. Just uncoment the part I mention above.

  3. #3
    Join Date
    Sep 2005
    Posts
    11

    Re: overwrite virtual template methods

    Hi Itcmelo,
    thanks for the response. But I think I didn't make clear, what the problem is.
    So I try once more (I cannot provide the complete and "real" code because it's far too much)
    Code:
    //This is a template
    template class A
    {
    public:
        virtual bool IsValid () const
        {
            return IsValid (mMemberValue);
        }
        /*...*/
    protected:
        virtual bool IsValid (int value)const
        {
           /*....*/
        }
    private:
        int mMemberValue;
    };
    
    //This is a class derived from template A
    class B : public A
    {
        public:
            virtual bool IsValid() const; //<<<<<- The error occurs here!
        /*....*/
    };
    In the above case the compiler complains about B::IsValid() hiding A::IsValid(int).
    If A was a class, this works. I did similar things a million times before.
    So I guess this has something to do with the template...

    chabba

  4. #4

    Re: overwrite virtual template methods

    You can't redeclare it or it will confuse the compiler. You need to provide an actual implementation instead. You can do that either in the B class or below it somewhere.

  5. #5
    Join Date
    Sep 2005
    Posts
    11

    Re: overwrite virtual template methods

    Hi originalfamousjohnsmith,
    yes, the compiler IS confused. That's right. But the thing is, that template A provides an implementation for IsValid(). Is Valid() is virtual. Class B wants to overwrite IsValid() and implement
    its own behaviour. That is nothing unusal.
    (In the full source file template A offers more virtual functions, that had always been successfully overwritten).
    The ONLY difference with IsValid() is, that IsValid() exists twice in the template with a different signature. And the compiler complains about hiding the base method with the OTHER signature.

    If I overwrite IsValid(), it complains about hiding IsValid(int)! And the other way round. This is, what I do not understand. So far, this seems to me that this might be a bug in the compiler (what is not very suprising, because it's B*RL*ND C++).

  6. #6
    Join Date
    Oct 2008
    Location
    Singapore
    Posts
    195

    Re: overwrite virtual template methods

    The compiler is correct. In C++, if a derived class declares a function with the same name, it hides the base class version, even if the signature differs.

  7. #7
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: overwrite virtual template methods

    Quote Originally Posted by chabbawoggie View Post
    In the above case the compiler complains about B::IsValid() hiding A::IsValid(int).
    If A was a class, this works. I did similar things a million times before.
    So I guess this has something to do with the template...
    The code you posted is not valid C++, so I can't be sure, but I don't think this is about templates at all. Did you try the solution ltcmelo suggested (adding a using statement to prevent the function from being hidden)?

    Also, what do you mean with "If A was a class"? Is A not a class in your example? If so, what is it?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: overwrite virtual template methods

    Quote Originally Posted by chabbawoggie View Post
    So I try once more (I cannot provide the complete and "real" code because it's far too much)
    Every compiler error can be reproduced with a minimal example. Instead of us having to come up with code, maybe you can post a real example that demonstrates the error. Right now, you're only concluding that something is wrong with the compiler -- we will know well enough if this is the case with real code being posted.
    Code:
    //This is a template
    template class A
    You could have started by providing the proper syntax for a C++ template. Then just add dummy, empty functions with bogus return values, i.e. enough so the code compiles and you get an error.

    As a matter of fact, that is exactly what you should have done yourself even before posting, so as to possibly solve the problem yourself. Anytime I get a compiler error, I break it down to the simplest, bogus, but compilable example, and see if the compiler accepts the code. If it doesn't compile, OK, I have a small piece of code to test on another compiler. If that same piece of code compiles on another compiler, I have some code that I can post here, or even give it to the compiler authors/engineers to see if it is valid or not.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Question Re: overwrite virtual template methods

    Quote Originally Posted by ltcmelo View Post
    I cannot say that for sure because you didn't post all the code.

    The hidding situation is in accordance to the standard. This happens even for non-templates classes. The C++ lookup mechanism will not look further for in other scopes if it already finds a name match in the current class. Example:

    Code:
    struct A
    {
      bool IsValid(int i) const {return true;}
    };
    
    struct B : A
    {
      bool IsValid(int x, int y) const {return true;} 
    
      //Uncomment below to fix.
      //using A::IsValid; 
    };
    
    int main()
    {
      B b;
      int i = 10;
      bool x = b.IsValid(i); //Error, only IsValid(int, int) from B is visible.
      
      /* ... */
    }
    One way to fix it is with a using directive. Just uncoment the part I mention above.

    I don't understand this example. the OP posted declarations that were virtual. You are talking about the hiding issue with non-virtual functions which is a totally different kind of problem isn't it?

  10. #10

    Re: overwrite virtual template methods

    Forgive me if my terminology is off, but basically you need to 'specialize' the template for that implementation. I've had the exact problem, assuming this is being explained at all well.

    So if you have:

    Code:
    template <typename type> class Base
    {
        void someFunc(){}
    };
    
    class Child: public Base<type>
    {
    
    }
    
    template Base<type>::someFunc()
    {
    
    }

  11. #11
    Join Date
    Sep 2005
    Posts
    11

    Re: overwrite virtual template methods

    Ok, here is a "full featured" example. Meanwhile I installed VS Express. This compiles without any warning (except for warning level 4, where it complains about unreferenced parameters).
    But Borland C++ says "B::IsValid()" const hides virtual function "A::<Dummy>IsValid(int) const".
    Code:
    //File TemplateA.h
    
    template <class T> class A
    {
    public:
        virtual bool IsValid() const
        {
            int i = 5;        
            return IsValid(i);
        }
    protected:
        virtual bool IsValid(int value) const
        {
            return false;
        }
    };
    //-------------------------------------------------
    // File B.h
    
    #include "TemplateA.h"
    
    class Dummy
    {
    };
    
    class B : public A<Dummy>
    {
    public:
        B(void);
        ~B(void);
        virtual bool IsValid() const;
    };
    //------------------------------------------------
    //File B.cpp
    
    #include "B.h"
    
    B::B(void)
    {
    }
    
    B::~B(void)
    {
    }
    
    bool B::IsValid() const
    {
        return true;
    }
    I know, that it only produces "only" a warning with Borland, but I take warnings seriously and this special warning makes me a little nervous as I said before.

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: overwrite virtual template methods

    Quote Originally Posted by chabbawoggie View Post
    Ok, here is a "full featured" example. Meanwhile I installed VS Express. This compiles without any warning (except for warning level 4, where it complains about unreferenced parameters).
    But Borland C++ says "B::IsValid()" const hides virtual function "A::<Dummy>IsValid(int) const".
    Here is what Comeau C++ has to say:
    Code:
    Thank you for testing your code with Comeau C/C++!
    Tell others about http://www.comeaucomputing.com/tryitout !
    
    Your Comeau C/C++ test results are as follows:
    
    Comeau C/C++ 4.3.10.1 (Oct  6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
    Copyright 1988-2008 Comeau Computing.  All rights reserved.
    MODE:strict errors C++ C++0x_extensions
    
    "ComeauTest.c", line 22: warning: overloaded virtual function
              "A<T>::IsValid [with T=Dummy]" is only partially overridden in class
              "B"
      class B : public A<Dummy>
            ^
    
    
    In strict mode, with -tused, Compile succeeded (but remember, the Comeau online compiler does not link).
    Compiled with C++0x extensions enabled.
    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Aug 2005
    Location
    San Diego, CA
    Posts
    1,054

    Lightbulb Re: overwrite virtual template methods

    Since we are only dealing with a warning, have you tried testing the class? Does it perform as expected? Have you created a unit test like application that calls the member functions in question and can you verify that the correct functions are called by setting breakpoints and stepping into the code with the debugger? Sorry, but I don't understand the warning that you are getting either.

  14. #14
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: overwrite virtual template methods

    Quote Originally Posted by kempofighter
    I don't understand this example. the OP posted declarations that were virtual. You are talking about the hiding issue with non-virtual functions which is a totally different kind of problem isn't it?
    Quote Originally Posted by kempofighter
    Sorry, but I don't understand the warning that you are getting either.
    The name hiding applies whether the member functions are virtual or non-virtual. Consequently, a correct solution to the problem is:
    Code:
    class B : public A<Dummy>
    {
    public:
        using A<Dummy>::IsValid;
    
        B(void);
        ~B(void);
        virtual bool IsValid() const;
    };
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  15. #15
    Join Date
    Jan 2008
    Location
    California, USA
    Posts
    822

    Re: overwrite virtual template methods

    I agree that qualifying the full name is the solution.
    But I'm morw with kempofighter on this.
    Quote Originally Posted by itcmelo
    Code:
    int main()
    {
      B b;
      int i = 10;
      bool x = b.IsValid(i); //Error, only IsValid(int, int) from B is visible.
      
      /* ... */
    }
    call to the b.IsValid was an error even before it made
    because it was called on the object, not through a reference type.
    so in this case,
    my understanding is that it was the vTable lookup mechanism that called b.IsValid(i) invalid,
    not the name hiding.
    I believe Paul was right on this when he showed the comeau version of the error
    Code:
    #include <iostream>
    
    template <typename T>
    struct Base
    {
        Base() : x(T()) {}
        virtual ~Base(){}
    
        virtual void call(const T y) const
        {
            std::cout << x + y;
        }
        virtual void call() const
        {
            std::cout << x;
        }
    protected:
        T x;
    };
    
    struct Derived : public Base<int>
    {
        virtual void call(const int y) const
        {
            std::cout << x + y;
        }
    
    };
    
    int main()
    {
        Derived d;
        Base<int>& ref = d;
        ref.call(); // valid with a warning
    }
    Here, we're not using the using declaration.
    I looked up Scott Meyer's effective C++,
    and under "Never redefine an inherited non-virtual function",
    he's also using reference types to illustrate the behavior
    If name hiding does occur before name look up happens in virtual overload resolution,
    (which I believe should happen afterwards)
    then like kempofighter, I'm lost as to why.
    Last edited by potatoCode; November 3rd, 2009 at 02:13 PM. Reason: fixed some typo

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured