这是因为在这种情况下,基类函数不包含在重载解析中。类似的情况是在内部作用域中声明的函数 - 它们不会重载在外部作用域中声明的函数(参见下面的示例)。你可以想象派生类作用域嵌套在基类作用域内。
一旦编译器发现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