2

Why there's no ambiguity in the expression d.f(1); below in main() between Base::f(int) and Derived::f(int) ?

class Base
{
    public:
    void f(int i) {}
    void f(int i, int j) {}
};

class Derived : public Base
{
    public:
    using Base::f;
    void f(int i) {}
};

int main()
{
    Derived d;
    d.f(1);
}
Belloc
  • 6,318
  • 3
  • 22
  • 52

3 Answers3

3

As others have written, there is no ambiguity because Derived::f(int) hides Base::f(int). You were probably expecting this to be the case only in the absence of the using declaration:

using Base::f;

But hiding still applies. Paragraph 7.3.3/15 of the C++11 Standard specifies:

When a using-declaration brings names from a base class into a derived class scope, member functions and member function templates in the derived class override and/or hide member functions and member function templates with the same name, parameter-type-list (8.3.5), cv-qualification, and ref-qualifier (if any) in a base class (rather than conflicting).

It also provides an example quite similar to yours (see how the expression p->f(1) does not result in ambiguity, and D::f is picked instead):

struct B {
    virtual void f(int);
    virtual void f(char);
    void g(int);
    void h(int);
};

struct D : B {
    using B::f;
    void f(int); // OK: D::f(int) overrides B::f(int);
    using B::g;
    void g(char); // OK
    using B::h;
    void h(int); // OK: D::h(int) hides B::h(int)
};

void k(D* p)
{
    p->f(1); // calls D::f(int)
    p->f(’a’); // calls B::f(char)
    p->g(1); // calls B::g(int)
    p->g(’a’); // calls D::g(char)
}
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • +1 Is there any explanation for this, that is, why did they do it this way? – Belloc Jul 11 '13 at 20:10
  • @user1042389: I can't give you a strong answer on that. In fact, I don't know. I can guess the rationale is, maybe, that the function in the derived class is still considered to be "more specific or more appropriate" than the version in the base class to resolve a call, and therefore it is picked rather than raising an ambiguity. But again, it's just a quick wild guess and you shouldn't take it as anything more than that :) – Andy Prowl Jul 11 '13 at 20:13
2

The function in the derived class hides the function in the base class.
This is called shadowing.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
1

Because the static type of d is Derived, and Derived::f(int) hides Base::f(int).

John Dibling
  • 99,718
  • 31
  • 186
  • 324