我似乎无法在没有确定基类的情况下调用基类的方法,而这似乎是因为我重载了该方法。如果我没有重载该方法,那么编译器不会抱怨。以下是我想做的一个例子:
struct BaseClass {
template <typename T> T& foo(T& t) {
return t;
}
};
class ChildClass: public BaseClass {
public:
// The presence of this template causes compiler confusion
template <class T> T& foo(T& t, int szl) {
return t;
}
template <class T> int bar(T& t) {
// But if I scope this as BaseClass::foo(...) it's all good
return foo(t);
}
};
int main() {
int t = 1;
ChildClass c;
c.bar(t);
}
如果在bar(...)中我调用BaseClass :: foo(...),编译器不会抱怨,但我没有看到任何歧义,所以我很困惑为什么我需要这样做。
答案 0 :(得分:3)
当编译器尝试将函数名称与函数匹配时,它会分两步完成。在第一步中,它找到与给定名称匹配的所有函数。如果它找到多个函数,它会尝试重载解析的逻辑来找到最佳匹配函数。
在第一步中,如果编译器在类中找到一个名称,它将停止在基类中查找相同名称的函数。在您的情况下,由于它在foo
中找到了ChildClass
,因此会停止在foo
中搜索名为BaseClass
的函数。但是,唯一匹配的foo
与调用不匹配,编译器报告错误。
如何解决问题:
使用您在帖子中描述的方法。致电BaseClass::foo(...)
。
将foo
的所有BaseClass
纳入ChildClass
的范围。
class ChildClass: public BaseClass {
public:
using BaseClass::foo;
template <class T> T& foo(int baz, T& t, int szl) {
return t;
}
template <class T> int bar(T& t) {
return sizeof(foo(1, t)); // Should work.
}
};
答案 1 :(得分:2)
从C ++标准3.3.10第1段:
可以通过显式声明同名来隐藏名称 嵌套的声明性区域或派生类
ChildClass::foo
会影响BaseClass::foo
的定义。您需要将它带入范围的是using
指令:
class ChildClass: public BaseClass {
public:
using BaseClass::foo;
template <class T> T& foo(int baz, T& t, int szl);
};
答案 2 :(得分:0)
您需要using
,例如:
using BaseClass::foo;