多继承基类时类模板参数方法的模板解析失效:原因与解决
问题解答
为什么多继承下的同名函数无法基于签名解析?
这是C++名字查找规则导致的:
- 调用
func(1)这类语句时,编译器首先执行名字查找:从当前函数作用域开始,依次查找派生类作用域、基类作用域。 - 多继承场景中,两个基类都包含名为
func的成员,名字查找阶段会找到多个独立的func名字(来自不同基类),此时编译器直接判定为名字歧义,不会进入后续的重载解析阶段。 - 全局函数
f_func的情况不同:全局作用域的名字查找会收集所有同名函数形成一个重载集,之后再根据参数进行重载解析,因此能正常工作。
模板基类有没有特殊事项?
你的模板基类案例和非模板的Conflicted_P本质完全一致,不存在模板特有的额外问题。Ambiguous_C<int>和Ambiguous_C<float>是两个独立的不同类,它们的func成员只是恰好同名,和两个普通基类Ambiguous_P1/Ambiguous_P2的情况没有区别。
如何实现无需显式指定基类的调用?
可以通过**using声明**将所有基类的func成员引入派生类的作用域,让它们形成一个重载集,这样就能正常进行重载解析:
针对模板基类的解决代码:
template<typename T> struct Ambiguous_C { void func(T); }; struct Conflicted_C : public Ambiguous_C<int>, Ambiguous_C<float>{ // 把两个基类的func引入派生类作用域 using Ambiguous_C<int>::func; using Ambiguous_C<float>::func; void test (){ func(1); // 正常编译,匹配Ambiguous_C<int>::func func(1.1f); // 正常编译,匹配Ambiguous_C<float>::func } };
针对非模板多继承的解决代码:
void f_func(int); void f_func(float); struct Ambiguous_P1 { void func(int); }; struct Ambiguous_P2 { void func(float); }; struct Conflicted_P : public Ambiguous_P1, Ambiguous_P2{ using Ambiguous_P1::func; using Ambiguous_P2::func; void test() { func(1); // 正常编译,匹配Ambiguous_P1::func func(1.1f); // 正常编译,匹配Ambiguous_P2::func f_func(1); f_func(1.1f); } };
原理:using声明将基类的func成员提升到派生类作用域,此时名字查找只会在派生类找到这两个func(作为同一个重载集的成员),编译器会跳过基类的名字查找,直接进入重载解析阶段,根据参数匹配正确的函数。
内容的提问来源于stack exchange,提问作者Rddvldny
相关产品推荐
相关产品推荐

