简体   繁体   中英

Cannot find baseclass function if baseclass has two functions of same name

I have a baseclass that has two functions of same name but with different signatures in a 2-level inheritance.

struct A {
    virtual void f(int) { }
    virtual void f(int, int) { };
    virtual void f1(int) { }
};

struct B: public A { };

struct C: public B {
  void f(int, int) { }
  void f1(int) { }
};

int main() {
 C obj;
 obj.f1(0);
 obj.f(0,0);

 obj.f(0);    // (1) cannot be found
 obj.B::f(0); // (2) works

}

I would have expected my compiler (gcc-4.3.2) to find the correct definition at (1) , but I get

g++     main.cpp   -o main
main.cpp: In function 'int main()':
main.cpp:20: error: no matching function for call to 'C::f(int)'
main.cpp:10: note: candidates are: virtual void C::f(int, int)
distcc[2200] ERROR: compile main.cpp on localhost failed
make: *** [main] Error 1

(2) on the other hand works.

What do I need to fix to make (1) work in general?

Write using A::f inside the definition of C.

You are a victim of name hiding! void C::f(int, int) hides void A::f(int) , just because.

The C++ name lookup rules have it so that if a name is redefined in one scope, all overloads of that name are hidden.

But you can use using to help. Like this:

class A {
    public:
    int f(int x) { cout << "A::f 1\n"; }
    int f(int x, int y) { cout << "A::f 2\n"; }
};

class B : public A {
    public:
    using A::f;
    int f(int x) { cout << "B::f 1\n"; }
};

int main()
{
    B b;

    b.f(27, 34);

    return 0;
}

Output is:

A::f 2

The short answer to "why" is "because that's how overloading works." You are hiding the f(int) overload in C. The longer answer is much longer.

You can un-hide it by doing this:

struct C: public B {
  using A::f;
  void f(int, int) { }
  void f1(int) { }
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM