Search code examples
c++classinheritanceoverloadingname-lookup

Why is it a warning to declare an unambiguous non-virtual overload of a virtual function?


I've been reading everywhere I can find and I just can't understand what the warning GCC is giving me, is upset about. I have this code:

class A;
class B;

class Upper
{
    virtual void foo(A& a);
};

class Lower : public Upper
{
    void foo(B& b);
};

and GCC gives me this error:

$ g++ -Wall -O2 -c -o /tmp/over.o /tmp/over.cpp
/tmp/over.cpp:6:18: warning: 'virtual void Upper::foo(A&)' was hidden [-Woverloaded-virtual=]
    6 |     virtual void foo(A& a);
      |                  ^~~
/tmp/over.cpp:11:10: note:   by 'void Lower::foo(B&)'
   11 |     void foo(B& b);
      |          ^~~

I just don't get it. Maybe someone needs to use small words. It's clear (to me) that these two methods are completely unambiguous and if I call foo(a) with an instance of class A I would call the virtual method and if I call foo(b) with an instance of class B I would call the non-virtual method. So, what's the problem here that the compiler is complaining about?

I've seen many questions where the overloaded methods could be ambiguous, such as argument of int vs. char or whatever, but here there's no possibility of confusion, which leaves me, well, confused!


Solution

  • The problem is that if you will write for example (I suppose that the functions are public)

    A a;
    Lower().foo( a );
    

    the compiler will issue an error because the function foo

    void foo(B& b);
    

    declared in the class Lower hides the virtual function foo declared in the base class Upper.

    You could resolve the problem for example with using declaration

    class Lower : public Upper
    {
    public:
        using Upper::foo;
        void foo(B& b);
    };
    

    In this case for objects of the class Lower you could call the both functions foo.