C++模板:名称查找
2014-11-23 20:37
204 查看
在编译模板的时候,编译器会分两个阶段去解析遇到的名称,第一个阶段解析不依赖于模板参数的名称,第二个阶段解析依赖于模板参数的名称,下面举个简单的例子来说明这一点:
error:there are no arguments to 'g' that depend on a template parameter, so a declaration of 'g' must be available.
template<class T> class X { public: typedef int E; }; typedef double E; template<class T> class Y : public X<T> { public: E f() {} };这个例子中定义了两个类模板,其中Y派生于X,在X中我们给int取了个别名E,接着在全局作用域中给double也取了个别名E,在Y中有一个函数f(),它的返回值类型为E,那么这个E到底是double呢,还是int?结果是double,因为f()不依赖与模板参数T,所以它在第一阶段就会被解析,而它的基类X<.T>在第二阶段才会被解析,所以解析f()的时候只能看到全局作用域里的typedef double E。如果大家心里有疑问,我们可以看看非模板类的情况:
class X { public: typedef int E; }; typedef double E; class Y : public X { public: E f() {} }; int main(){ Y y; cout<<typeid(y.f()).name()<<endl; return 0; }这个例子中都是普通的类,通过main函数的测试,可以看到f()的返回类型变成了int。接下来我们再来看一个例子:
void g() { cout<<"gobal::g()"<<endl; } template<class T> class X { public: typedef int E; void g() { cout<<"X::g()"<<endl; } }; typedef double E; template<class T> class Y : public X<T> { public: E f() { g(); this->g(); } }; int main(){ Y<char> y; cout<<typeid(y.f()).name()<<endl; y.f(); return 0; }这个例子中首先定义了一个全局函数g(),接着定义了类模板X,在X中定义了一个成员函数g(),类模板Y依然继承于X,在Y中的f()中“以两种方式”调用了g(),那么这两种方式调用的是同一个g()吗?答案是:不是,第一种方式调用了全局的g(),而第二种方式调用了基类的g(),原因在于当编译器遇到第一种方式的g()时,发现它没有表现出要依赖于模板参数,所以认为它不依赖于模板参数,因而在第一阶段就进行了解析,此时X<T>尚未解析,所以g()是全局的g(),通过第二种方式调用时,用this指针指出g()是依赖于当前对象的,也就依赖于模板参数,因而会在第二阶段解析,那时基类也会先于Y进行了解析,所以this-->g()调用了基类的g()。同样,我们可以看看普通类的情况:
void g() { cout<<"gobal::g()"<<endl; } template<class T> class X { public: typedef int E; void g() { cout<<"X::g()"<<endl; } }; typedef double E; template<class T> class Y : public X<T> { public: E f() { g(); this->g(); } }; int main(){ Y<char> y; cout<<typeid(y.f()).name()<<endl; y.f(); return 0; }结果会发现,两次都调用了基类X的g(),这个例子告诉我们,在类模板中,如果需要使用成员函数,需要通过this指针来指定,而不能像在普通类中那样省略到this指针,事实上,如果不用this指针来指定,而又没有全局函数g(),编译时会出现如下错误:
error:there are no arguments to 'g' that depend on a template parameter, so a declaration of 'g' must be available.
相关文章推荐
- C++的名称查找顺序
- C++模板实现的二叉排序(查找)树
- C++模板中的名称
- 平衡二叉查找(AVL)树(C++模板实现)
- C++ CFileFind() 查找当前路径下所有文件夹名称
- 基于C++模板的二分查找
- C++模板二段名字查找
- C++ template —— 模板中的名称(三)
- 二分查找c++简单模板
- C++模板:二分查找
- 立此存照(19)[C++]C++中的名称查找(name lookup)
- C++模板二段名字查找方法
- 二分查找模板C++
- C++名称查找与ADL
- C++ 名称查找规则之 Koenig lookup
- [C++] 模板引入的变量名查找问题
- C++ 名称查找规则之 Koenig lookup
- C++模板&二段式名字查找
- C++实现获取DOTA玩家名称(反汇编查找指针地址和跨进程读取war3内存)
- dotNet中ArrayList的C++模板简单实现