hochl
hochl

Reputation: 12930

How to fix overloaded function with different signature

I am in the process of integrating a code base from another developer. I have stumbled over the following situation:

#include <iostream>

struct A
{
    virtual void test(int a)
    {
        std::cout << "A::test(" << a << ')' << std::endl;
    }
};

struct B : public A
{
    // using A::test;

    void test(int a, int b)
    {
        std::cout << "B::test(" << a << ", " << b << ')' << std::endl;
        A::test(a);
    }
};

int main()
{
    B b;
    b.test(1, 2);
}

Compiling this code gives no warnings with g++ -Wall, but with clang++ -Wall I get:

x.cpp:15:11: warning: 'B::test' hides overloaded virtual function [-Woverloaded-virtual]
        void test(int a, int b)
             ^
x.cpp:5:19: note: hidden overloaded virtual function 'A::test' declared here: different number of parameters (1 vs 2)
        virtual void test(int a)
                     ^
1 warning generated.

Output in both cases would be:

B::test(1, 2)
A::test(1)

How to resolve this situation? For me there is no clear path, since it is unclear what is the intention of the original programmer.

Is there a canonical way to overload A::test and get rid of the warning in a way where I need not use -Wno-overloaded-virtual?

Current solution:

class B: public A
{
    private:
    using A::test;

    public:
    ...
};

This gets rid of the warning and will give an error if calling b.test(1). It still makes it possible to call A::test on it of course ...

Upvotes: 0

Views: 580

Answers (2)

UKMonkey
UKMonkey

Reputation: 6983

While you could make test(int) private in B, which will remove the warnings; you will end up with the situation that someone could trivially pass it as an "A" object and then call test(int) on it anyway. I would not worry about the intentions of the original engineer since there's a work around to call test(int) and make sure that what it does makes sense; even if that means throwing or failing to compile if used.

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409176

A possible solution or workaround might be to pull A::test into the scope of B, like

struct B : A
{
    using A::test;
    ...
};

Then you can use plain test(a) and A::test should be called.

Upvotes: 2

Related Questions