在this线程中,接受的答案的作者解释了为什么编译器无法解析派生类中重写的方法。但是,该示例与类型转换分辨率相关,即基础和派生重载方法仅具有一个参数,并且歧义仅限于该参数类型。
但是当重载方法具有不同数量的参数时,模糊性在哪里,如本例所示?
请注意,我不是在问为什么该示例会产生编译错误,我在问为什么语言是这样设计的。
#include <iostream>
using namespace std;
class A
{
public:
inline int f(int x) { return x; }
};
class B: public A
{
public:
inline int f(int x, int y) { return x+y; }
};
int main()
{
B b;
cout << b.f(1) << endl; // COMPILE ERROR
cout << b.f(1,2) << endl;
}
答案 0 :(得分:1)
您收到编译器错误的原因是f
类A
隐藏了f
类<{1}}。
当编译器执行成员名称查找时,仅当在对象的类中找不到名称时才使用基类,因此如果基类中的成员具有适合您的参数列表,则无关紧要调用
来自标准:
10.2.5否则(即C不包含f的声明或结果声明集为空),S(f,C)为 最初是空的。如果C具有基类,则在每个直接基类子对象Bi中计算f的查找集 , 并将每个这样的查找集S(f,Bi)依次合并为S(f,C)。
答案 1 :(得分:1)
在C ++中,只要在其中一个基类中找到所请求的名称,名称查找就会停止查找其他名称。
在您的情况下,名称f
在B
中定义,因此编译器停止查看其他基类。
您可以使用使用声明使A :: f可见:
class B: public A
{
public:
using A::f;
int f(int x, int y) { return x+y; }
};
答案 2 :(得分:0)
编译器将在类f
中查找函数B
的实现。编译器找到了这样一个实现,它有两个参数。您只提供了一个参数,因此存在错误。
答案 3 :(得分:0)
你如何消除派生类中没有意义的重载?即使在您的示例中,假设如果您有B实例,也希望禁止使用单参数函数。正如现在所写,您已经删除了单参数版本(好吧,至少在B实例的上下文中将其从名称解析中删除)。但是,如果您仍希望该版本可用,则可以在类中指定using A::F;
以引入单参数版本。