深度探索c++对象模型之template中的名称决议方式
来源:互联网 发布:oracle查看数据库 编辑:程序博客网 时间:2024/04/27 14:14
// scope of the template definition【模板定义域】extern double foo(double);template<class type>class ScopeRules{public: void invariant() { _member = foo( _val ); }type type_dependent() { return foo( _member ); }private: int _val; type _member;}
然后第二种情况也举例说明:
// scope of the template instantiation【模板具现域】extern int foo(int);ScopeRules<int> sr;
// scope of the template instantiationsr.invariant();
那么在invariant中的【_member = foo( _val );】,究竟会调用哪一个函数实体呢?是scope of the template declaration【模板声明域】中的“extern double foo( double )”,还是scope of the template instantiation【模板具现域】中的“extern int foo( int )”?如果您因为在我们例子中用int具现的ScopeRules而选择了后者,那么很可惜您选错了,因为正确答案是意料之外的double foo。。。
至于原因,让我们来看一下书中的解释:在template之中,对于一个非成员名字【如本例中invariant里面foo】的决议结果,是根据这个名字的使用是否与“用来具现该模板的实际参数类型”有关与否来决定的,如果非成员名字的使用和具现模板用的实际参数没有关联,那么就以“scope of the template declaration【模板声明域】”来决定名字归属;然而如果它们有关联,那么就以“scope of the template instantiation【模板具现域】”来决定名字归属;回头看我们上面的例子可以发现,invariant中的foo与我们用来具现模板的参数int没有关联,所以使用“scope of the template declaration”中的double版本foo函数,下面是更详细的解释:
// the resolution fo foo() is not dependent on the template argument【foo函数的决议结果并不依赖于模板参数】_member = foo( _val );_val在我们的模板声明中,已经被定义成一个int类型,也就是说,_val是一个类型不会变的模板类成员,无论具现这个ScopeRules的实际参数是什么类型,都不会影响到_val本身。还有,函数的决议结果只和函数的signature【原型】有关,和函数的返回值类型什么的无关,所以,模板具现后的_member类型并不会影响到哪一个foo函数体被选中,总之就是foo的调用与具现ScopeRules的参数毫无关联!所以调用操作必须根据“scope of the template declaration”来决议,而在“scope of the template declaration”域中,只有一个double版本foo函数,所以自然只有一个候选者。【此外要注意的是,这种行为不能以一个简单的宏扩展——比如使用一个#define宏——重现之】。
下面让我们来看看“与具现模板类型”【type-dependent】有关的用法:
sr.type_dependent();这个函数的内容如下:
return foo(_member);这个例子与上一个例子不同,因为_member肯定与具现ScopeRules的参数有关:该参数将决定_member的实际类型。所以这一次foo必须在“scope of the template instantiation”域中被决议,到了这个域中就有了两个foo版本函数,但由于_member的被具现后的类型是int,因此这次就是int版本的foo函数出线。但是,如果ScopeRules是被unsigned int或long具现出来,那么这里的foo选择就会模糊不清。最后,如果ScopeRules是被某一个用户自己的自定义类类型具现出来,而该类没有针对int和double实现conversion运算符【转换运算符】,那么foo的调用操作会被标识错误!但不管情况如何,都是以“scope of the template instantiation”来决定,而不是“scope of the template declaration”来决定。
这意味着编译器必须保持两个scope contexts【上下文范围】:
1):“scope of the template declaration”,用来专注于一般的template class;
2):“scope of the template instantiation”,用来专注于特定的实体;
编译器的resolution【决议】算法必须决定哪一个才是适当的scope,然后在其中搜索适当的name。
- 深度探索c++对象模型之template中的名称决议方式
- C++对象模型——Template中的名称决议方式 (第七章)
- 深度探索c++对象模型之template的错误报告
- 深度探索c++对象模型之template的具现行为
- 【C++】深度探索C++对象模型之Function语意学
- 深度探索C++对象模型
- 【C++】深度探索C++对象模型之站在对象模型的顶端
- 深度探索C++对象模型之前言
- 深度探索C++对象模型之C++对象模型笔记
- 深度探索C++对象模型---Function语义学之Member的各种调用方式
- 【C++】深度探索C++对象模型之虚拟成员函数(virtual member function)
- 【C++】深度探索C++对象模型之执行期语意学
- 【C++】深度探索C++对象模型之构造、析构、拷贝语意学
- 深度探索C++对象模型之局部静态对象
- 《深度探索C++对象模型》读书笔记之关于对象
- 深度探索c++对象模型之临时对象的传说
- 【C++】深度探索C++对象模型之类存储
- 《深度探索C++对象模型》
- String与StringBuffer与StringBuilder
- 翻译《有关编程、重构及其他的终极问题?》——4.小心--操作符,请把表达式放在括号中
- POJ 2036 Wireless Network
- java核心技术----Object类
- SDL_PollEvent函数
- 深度探索c++对象模型之template中的名称决议方式
- android手指个数识别项目
- 解决listview焦点抢夺问题
- Activity生命周期
- Android自定义UI实战(基础篇3)---图标圆弧运动
- 无论如何,你该在大城市再坚持下
- 数据库应用系统 第一章上机4
- RxBinding的一些简单使用
- 数据库 第一章