为何模板包装类中需用this->/基类名调用基类成员函数?
模板类继承依赖基类时,为何直接调用基类成员函数会报错?
先看你给出的报错代码:
class A { public: void func1() {} }; template <typename wrapped_type> class B : public wrapped_type { public: void func2() { func1(); // 编译报错:C3861: 'func1': identifier not found } }; B<A> b;
这个问题的核心在于C++模板的依赖名称查找规则和延迟实例化特性,咱们慢慢说清楚:
为什么直接调用func1()会报错?
模板类的定义是「延迟编译」的——只有当你实例化模板(比如这里的B<A>)时,编译器才会真正去解析模板里的代码。但在处理模板定义阶段(还没实例化的时候),wrapped_type只是一个未知的模板参数,属于「依赖类型」。
这时候编译器处理func2()里的func1()时,会执行「非依赖名称查找」:它只会在当前作用域、全局作用域,以及模板定义时已经确定的非依赖基类里找名字,不会去碰「依赖基类」(也就是wrapped_type)的成员。因为此时编译器根本不知道wrapped_type里有没有func1,所以直接抛出“找不到标识符”的错误。
两种修复方式的原理
方式1:用this->func1()
void func2() { this->func1(); // 编译通过 }
this->相当于给编译器一个提示:func1是依赖于当前对象类型的名称,需要等到模板实例化的时候,再去整个类的继承层次(包括依赖基类wrapped_type)里查找。这时候编译器会把func1标记为「依赖名称」,延迟查找时机到实例化阶段,自然就能找到基类A里的func1了。
方式2:用wrapped_type::func1()
void func2() { wrapped_type::func1(); // 编译通过 }
这种方式是直接给func1指定了作用域——明确告诉编译器去wrapped_type这个基类里找。因为wrapped_type是模板参数,编译器会等到实例化时确定它的具体类型(这里是A),然后去对应的类中查找成员函数,所以也能成功找到func1。
内容的提问来源于stack exchange,提问作者kien
相关产品推荐
相关产品推荐

