1

I just stumbled across an compile error and I am wondering why this occurs.
The code:

struct Foo1
{
    virtual int foo() = 0;
};
struct Foo2 : Foo1
{
    virtual int foo(int i) = 0;
};
struct Bar : public Foo2
{
    virtual int foo() { return 0; }
    virtual int foo(int i) { return i; }
};
int main() {
    Bar b;
    Foo2* f2 = &b;
    b.foo();
    //f2->foo(); // this gives an error
    return 0;
}

The error on a gcc 4.8.1 is

error: no matching function for call to ‘Foo2::foo()’

I am wondering why the compiler cannot see the Foo1::foo function? I know that I can fix this by adding using Foo1::foo to the Foo2 class, but can anyone give me a reference to the standard why the compiler is not able to find the function by itself?

mkaes
  • 13,781
  • 10
  • 52
  • 72

2 Answers2

4

From N3797

3.3.10/3 Name hiding

In a member function definition, the declaration of a name at block scope hides the declaration of a member of the class with the same name; see 3.3.7. The declaration of a member in a derived class (Clause 10) hides the declaration of a member of a base class of the same name. see 10.2.

So Foo2::foo() hides Foo1::foo().

Rakib
  • 7,435
  • 7
  • 29
  • 45
  • 1
    This is the correct answer. The phenomenon is also called "name hiding" IIRC and basically states that declarations in a base class are hidden if there's a declaration with the same name in the derived class. It is by design to avoid some "contrived" behaviors. – Marco A. Jun 11 '14 at 10:34
3

The foo in the derived class hides the foo with different signature of the base class.

To say that you want the overloads of the base included you need to add a using declaration to Foo2:

struct Foo2 : Foo1
{
    using Foo1::foo;
    virtual int foo(int i) = 0;
};
sth
  • 222,467
  • 53
  • 283
  • 367