Rotem
Rotem

Reputation: 21917

Inheritance with two functions with different signatures hides the non-virtual function

Forgive the obscure title. It's likely a duplicate but I couldn't find the correct phrase.

Consider the following inheritance hierarchy.

class A
{
public:
    virtual void Foo(int i) { printf("A::Foo(int i)\n"); }
    void Foo(int a, int b) { Foo(a + b); }
};

class B : public A
{
public:
    void Foo(int i) override { printf("B::Foo(int i)\n"); }
};

class C : public B
{
public:
    void Bar() { Foo(1, 2); } //error C2660: function does not take two arguments
};

A has two methods named Foo with a different number of parameters. Only one of them is virtual.
B overrides the virtual method.
C tries to call the non-virtual method and encounters an error.

Calling the method as A::Foo(1, 2) does work fine.

Question: Why can't the compiler deduce that the correct method is found on A?

It seems odd we would have to explicitly add A:: in a call such as:

C c;
c.A::Foo(1, 2);

Upvotes: 2

Views: 95

Answers (1)

songyuanyao
songyuanyao

Reputation: 172874

Because the member function named Foo is found at the class scope of B, and then name lookup stops, so the Foo in class A is not visible, and won't be considered for overload resolution, even if the version in class A is more appropriate. It is name hiding.

You can use using to introduce them into the same scope, and make overload resolution work as you expect. Such as:

class C : public B
{
    using A::Foo;
    using B::Foo;
public:
    void Bar() { Foo(1, 2); }
};

See Unqualified name lookup

LIVE

Upvotes: 3

Related Questions