Fab*_*era 27 c++ templates class-hierarchy
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);
}
Run Code Online (Sandbox Code Playgroud)
呼叫d.f
是好的原因是什么,但是c.f
给出了
error: request for member ‘f’ is ambiguous
error: candidates are: template<class T> void B::f(T)
error: void A::f(int)
Run Code Online (Sandbox Code Playgroud)
Joh*_*ren 11
第一部分是由于成员名称查找,这就是它失败的原因.
我会推荐你: 10.2/2 Member name lookup
以下步骤在类范围C中定义名称查找的结果.首先,考虑类中及其每个基类子对象中的名称的每个声明.如果A是B的基类子对象,则一个子对象B中的成员名称f隐藏子对象A中的成员名称f.任何如此隐藏的声明都将被排除在考虑范围之外.由using声明引入的每个声明都被认为来自C的每个子对象,该子对象的类型包含using声明指定的声明.
如果生成的声明集不是来自相同类型的子对象,或者集合具有非静态成员并且包括来自不同子对象的成员,则存在歧义并且程序格式错误.否则该集合是查找的结果.
现在,关于模板功能的问题.
按照 13.3.1/7 Candidate functions and argument list
在候选者是函数模板的每种情况下,使用模板参数推导(14.8.3,14.8.2)生成候选函数模板特化.然后以通常的方式将这些候选人作为候选职能处理.给定名称可以引用一个或多个函数模板,也可以引用一组重载的非模板函数.在这种情况下,从每个功能模板生成的候选函数与该组非模板候选函数组合.
如果你继续阅读 13.3.3/1 Best viable function
如果出现以下情况,F1被认为是更好的功能:
F1是非模板函数,F2是函数模板特化
这就是为什么以下代码片段编译并运行非模板函数而没有错误:
D c;
c.f(1);
Run Code Online (Sandbox Code Playgroud)