Это связано с тем, что в этом случае функции базового класса не включены в разрешение перегрузки. Аналогичная ситуация связана с функциями, объявленными во внутренней области - они не перегружают функции, объявленные во внешней области (см. Примеры ниже). Вы можете представить, что область производного класса вложена в область базового класса.
После того как компилятор нашел D::insert
кандидат, он не будет выглядеть дальше в базовом классе. Если бы не было D::insert
, тогда компилятор будет искать базовый класс для метода insert
для вызова. Вы можете исправить это, вводя insert
имена функций из базового класса с:
using B::insert;
это будет ввести все B::insert
перегруженные функции в производном классе. Или, как вы говорите, вы можете явно вызвать базовый метод класса с:
d.B::insert(1)
Пример кода на то, как перегрузка работ таким же образом и в других контекстах:
namespace Outer {
void foo(double d) {
std::cout << "Outer::foo(double d)\n";
}
namespace Inner {
//using Outer::foo; // uncomment to see "Outer::foo(double d)" in output
void foo(int n) {
std::cout << "Inner::foo(int n)\n";
}
void callMe() {
foo(1.1);
}
}
}
int main() {
Outer::Inner::callMe(); // Outputes: Inner::foo(int n)
}
или:
void foo(std::string s) {
std::cout << "foo(std::string s)\n";
}
void foo(double d) {
std::cout << "foo(double d)\n";
}
void foo(int n) {
std::cout << "foo(int n)\n";
}
int main() {
void foo(int d); // comment out to see foo(double d) in output
foo(1.1); // outputs: "foo(int n)", foo(double d) is hidden
//foo("hello"); // ups, it wont compile - name lookup in c++ happens before type checking
// commenting out `void foo(int d);` above will fix this.
}
См. Https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule – Oktalist