Отменить скрытие имени, используя ключевое слово "using". Не работает в классе внуков

Например, в приведенной ниже программе я отменяю скрытие имен, используя ключевое слово "using". Если у меня есть базовый и один производный класс, я получаю ожидаемую неоднозначную ошибку вызова. Но если у меня есть два производных класса (child и grand child), то теперь child и grand child имеют одну и ту же перегруженную функцию, и я отменяю скрытие имени, используя ключевое слово "using". Но это скомпилировано и получено. Мой вопрос, почему я не получаю ошибку как "неоднозначный вызов перегруженной функции".

class baseNameHiding
{
protected:
int nameHidingexample(int t)
{
    cout<<"im baseeeeeeeeeeee"<<endl;
    return 0;
}
};
class derivedNameHiding:public baseNameHiding
{   
public:
    float nameHidingexample(float s)
    {
        cout<<"im derived"<<endl;
        return 0;
    }
    using baseNameHiding::nameHidingexample;

};
class grandDerivedNameHiding:public derivedNameHiding
{
public:
    float nameHidingexample(float f)
    {
        cout<<"im grand derived"<<endl;
        return 0;
    }
    using baseNameHiding::nameHidingexample;
    using derivedNameHiding::nameHidingexample;

};
int main()
{
    char a;float f = 0.0;
    derivedNameHiding derived;
    derived.nameHidingexample(0);
    grandDerivedNameHiding grandchild;
    grandchild.nameHidingexample(f);
    cin>>a;
} 


//output
im baseeeeeeeeeeee
im grand derived

1 ответ

Вы столкнулись со специальным правилом использования объявлений. C++14 [namespace.udecl]/15:

Когда объявление использования переносит имена из базового класса в область производного класса, функции-члены и шаблоны функций-членов в производном классе переопределяют и / или скрывают функции-члены и шаблоны функций-членов с одинаковыми именами, параметр-тип-список, cv -квалификация и ref-квалификатор (если есть) в базовом классе (а не конфликтующий). [...] [ Пример:

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)
}

- конец примера ]

Другие вопросы по тегам