如何正确调用C++模板化超类的构造函数?派生类初始化列表报错
错误根因
该编译报错源自C++模板场景下的依赖基类名字查找规则:
- 当前
Derived是持有模板参数Owning的模板类,它所继承的Base<Owning>属于依赖模板参数的特殊基类类型 - 按照语言规则,编译器在解析
Derived内部的非依赖名称(也就是初始化列表里直接书写的Base)时,不会自动到这类依赖基类的作用域中检索匹配名称 - 这种机制下,编译器根本不会把你写的
Base和实际继承来的Base<Owning>类关联起来,因此才会抛出“类Derived<Owning>不存在名为Base的字段”的错误。
可行修正方案
- 方案一:在初始化列表中显式书写带模板参数的完整基类名
把初始化列表中的调用从Base(new int(5))替换为Base<Owning>(new int(5))即可。由于Base<Owning>是和当前Derived模板参数强绑定的依赖名称,编译器可以正确将其解析为继承的基类,直接匹配对应的构造函数。 - 方案二:在
Derived类内部定义基类的类型别名
在Derived的类定义作用域内添加一行别名声明using Base = Base<Owning>;,之后在初始化列表中直接书写Base(...)的简化写法就可以被编译器正常识别,无需每次重复书写模板参数。
修正后的完整可编译代码
template<bool Owning> class Base { protected: Base() = default; Base(int * ptr) { //Do something } }; template<bool Owning> class Derived : public Base<Owning> { public: Derived() : Base<Owning>(new int(5)) {} private: // 若使用别名方案,可将上面的初始化调用替换为简化的 Base(new int(5)) using Base = Base<Owning>; };
注:由于
Base的构造函数为protected访问权限,Derived作为派生类完全有权限在自身的构造函数初始化列表中调用该构造,只要完成正确的名字解析就不存在访问权限相关的问题。
内容的提问来源于stack exchange,提问作者Xirema
相关产品推荐
相关产品推荐

