struct A {
void f(int x) {}
};
struct B {
template<typename T> void f(T x) {}
};
struct C : public A, public B {};
struct D {
void f(int x){}
template<typename T> void f(T x) {}
};
int main(int argc, char **argv) {
C c;
c.f<int>(3);
D d;
d.f<int>(3);
}
打电话的原因是什么d.f
很好,但是c.f
gives
error: request for member ‘f’ is ambiguous
error: candidates are: template<class T> void B::f(T)
error: void A::f(int)
第一部分是由于成员名称查找,这就是它失败的原因。
我建议您参考:10.2/2 Member name lookup
以下步骤定义了类范围内名称查找的结果,
C. 首先,类中和每个类中名称的每个声明
考虑其基类子对象。会员名f合二为一
如果 A 是基类,则子对象 B 隐藏子对象 A 中的成员名称 f
B 的类子对象。任何如此隐藏的声明都是
排除在考虑范围之外。这些声明中的每一个都是
由 using 声明引入的被认为是来自每个
C 的子对象,其类型包含声明
由 using 声明指定。
如果声明的结果集并非全部来自子对象
相同类型,或者集合具有非静态成员并包含成员
从不同的子对象来看,存在歧义,程序是
不规范的。否则该集合就是查找的结果。
现在,关于模板函数。
As per 13.3.1/7 Candidate functions and argument list
在候选者是函数模板的每种情况下,候选者
函数模板特化是使用模板生成的
参数推导(14.8.3、14.8.2)。然后处理这些候选人
作为候选人以通常的方式发挥作用。一个名字可以指一个
或多个函数模板以及一组重载
非模板函数。在这种情况下,候选函数
从每个功能模板生成的内容与一组
非模板候选函数。
如果你继续阅读13.3.3/1 Best viable function
F1 被认为是better函数,如果:
F1是非模板函数,F2是函数模板
专业化
这就是为什么以下代码片段编译并运行非模板函数没有错误:
D c;
c.f(1);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)