C++模板成员函数继承场景下编译失败的底层机制问询
C++代码编译报错底层原因解释
核心规则:C++ 名字隐藏(Name Hiding) 机制
C++的类成员名字查找遵循「先匹配名字、再做重载决议」的优先级:
- 当通过派生类对象调用成员函数时,编译器会优先在派生类作用域检索对应名字的成员
- 只要派生类中存在和目标调用同名的成员(不要求参数列表、函数属性匹配,不管是普通成员、虚函数还是模板函数都算),编译器就会停止向上到基类作用域查找,直接把派生类中找到的所有同名字成员作为重载候选集
- 只有派生类作用域完全找不到目标名字时,才会去基类作用域继续检索
对应代码的报错逻辑
你给出的代码正好命中了名字隐藏规则:
- 基类
MyBaseClass里有两个同名read成员:纯虚函数int read(unsigned, void*)、模板成员函数template<typename T> int read(T&) - 派生类
MyDerivedClass里定义了同名的int read(unsigned, void*)虚函数实现,直接把基类所有名为read的成员全部隐藏 - 调用
baseThang.read(a)时,baseThang是基类引用,查找范围在基类作用域,两个read都进入候选集,重载决议匹配到模板版本,编译正常 - 调用
thang.read(a)时,查找范围先到派生类作用域,只找到int read(unsigned, void*)这一个read候选,参数列表和传入的unsigned a不匹配,直接报编译错误
修复方案
两种常用修复方式二选一即可:
- 在派生类的public作用域添加
using MyBaseClass::read;,把基类的read名字引入派生类的重载候选集,编译器可以同时看到两个版本的read,正常匹配模板版本 - 调用派生类对象的模板
read时显式指定基类作用域:thang.MyBaseClass::read(a);,强制编译器到基类作用域检索成员
内容的提问来源于stack exchange,提问作者Russ Schultz
相关产品推荐
相关产品推荐

