模板类继承后找不到父类函数的问题

错误示例:

 1 template<class T> class List  
 2 {
 3         public: 
 4         void next(T*){
 5             cout<<"Doing some stuff"<<endl;
 6         }       
 7 };
 8 
 9 template<class T> class Special_List: public List<T>
10 {
11     public:
12         void do_other_stuff(T* item){
13                 next(item);
14         }       
15 };
16 
17 
18 int main(int argc, char *argv[])
19 {
20     Special_List<int> b;
21     int test_int = 3;
22     b.do_other_stuff(&test_int);
23 }

使用g++编译,出现如下错误:

1 template_eg.cpp: In instantiation of 'void Special_List<T>::do_other_stuff(T*) [with T = int]':
2 template_eg.cpp:27:35:   required from here
3 template_eg.cpp:18:25: error: 'next' was not declared in this scope, and no declarations were found by argument-dependent lookup at the point of instantiation [-fpermissive]
4 template_eg.cpp:18:25: note: declarations in dependent base 'List<int>' are not found by unqualified lookup
5 template_eg.cpp:18:25: note: use 'this->next' instead

解决方法:

1、

this->next(item)

2、

List<T>::next(item)

3、

1 template<class T> class Special_List: public List<T>
2 {
3 using List<T>::next;
4     public:
5         void do_other_stuff(T* item){
6                 next(item);
7         }       
8 };

具体原因:

模板的处理过程分为两步(标准编译,VS是另一种方式)。第一步,在类型实例化前,所有不依赖于模板参数的数据被查找和检查。第二部,类型确定,而后处理剩余的部分。

现在,在第一阶段,没有迹象表明next函数是依赖于模板参数的,因此它需要再类型例化前被处理。但是基类型是被当前模板例化的,且并不知道类型T会被例化成怎样的类,编译器无法进入基类中查找。

而this->next则将next加入了依赖模板的函数名单,这使得编译器会在第二阶段才查找next函数的实现,这时T是已知类型,基类List<T>也是已知的,编译器可以进入查找。

在处理的第二阶段,查找表只会查找参数依赖表中的函数并添加进表中。如果next函数是一个与T有关的namespace中,那么它会被查找添加,而如果它仅是基类的一个成员函数,那么它对于ADL是不可见的。对于next函数,编译器需要在查找表中检索next,而对于this->next,编译器查找的是this(在第二阶段模板类型例化后),之后才会查找next。

 

ADL(参数依赖查找,Argument-dependent lookup):http://www.cnblogs.com/zl1991/p/7718718.html

posted @ 2017-10-23 19:56  鸭子船长  阅读(1187)  评论(0编辑  收藏  举报