模板类继承中关于成员的二阶段查找过程


1.Parsing of a template. This phase occurs when a template definition is first seen 
by a compiler (point of definition [3]). During this phase, the lookup is completed
only for nondependent names.
2.Template instantiation. It happens when a template is instantiated, with template 
parameters substituted by the actual template arguments (point of instantiation). 
It is during this phase when the dependent names are looked up. 
上述是关于模板类的两阶段查找名字的过程。用中文描述就是:
1.模板定义阶段:刚被定义时,只有模板中独立的名字(可以理解为和模板参数无关的名字)参加查找
2.模板实例化阶段:实例化模板代码时,非独立的名字才参加查找
这个举个例子来说明一下:
#include<iostream>
using namespace std;

template<typename T>
class A
{
     public:    
	 void f() {   
	 	cout << "A::f()" << endl;    
	 }
};
template<typename T>
class B:public A<T>
{
    public:   
	void  g()
      { 
           f();//报错,这样写的话
           this->f();//A::f()
		   A<T>::f();//A::f()
      } 
};
int main(){
	B<int> b;
	b.g();
}
首先进入B的模板定义阶段,此时B的基类A<T>依赖于模板参数T,所以是一个非
独立的名字。所以在这个阶段,对于B来说A<T>这个名字是不存在的,于是A<T>::f()
也不存在。但此时这段代码仍旧是合法的,因为此时编译器可以认为f是一个非成员函数。
当稍晚些时候进入B的模板实例化时,编译器已经坚持认为f是非成员函数,纵使此时
已经可以查到A<T>::f(),编译器也不会去这么做。编译器会认为查找非成员函数没必要
去基类里面查找,所以这个时候就会找不到f了。于是就会报错。找不到f(no delcaration)。
那我们回过头来看this->f():
1.模板定义阶段:尽管没法查到A<T>::f(),但明晃晃的this->告诉编译器,f是一个成员函数
不是B类里,就是在B类的基类里,于是编译器记住了。
2.模板实例化阶段:此时编译器查找的对象是一个成员函数,首先在B中查找,没有找到
;然后在基类里查找,于是成功找到A<T>::f()。所以不会报错了
此分析来自:https://www.zhihu.com/question/31797003
分析完上述的过程,再分析一下这种情况:
template<typename T>
class A
{
     public:    
	 void f() {   
	 	cout << "A::f()" << endl;    
	 }
};
template<typename T>
class B:public A<T>
{
    public:   
	void  f()
      { 
           f();//报错,这样写的话
           this->f();//这样写的话也会报错了
		   A<T>::f();//A::f()
      } 
};
这样写的话,this->f()也会报错:
Segmentation fault (core dumped)
之所以会报这个错,是因为你在定义f()的时候,使用自己的this->f()调用,这样就会产生递归调用,所以也就会报上述的错误。

另外关于派生类中对于成员函数可见的方法,除了上述的两种:this->和A<T>::之外,还有一种方法就是使用using来查看。比如
class A
{
     public:    
	 void f() {   
	 	cout << "A::f()" << endl;    
	 }
};
template<typename T>
class B:public A<T>
{
    public:  
    using A<T>::f; //方法3,using来使得编译器可以去查找模板基类中的名字
	void  f()
      { 
           f();//这样就不会报错了
           this->f();//这样写的话也会报错了
		   A<T>::f();//A::f()
      } 
};

以上就是我目前了解到的关于模板类的成员查找的知识点。希望可以给你们一些帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值