C++对象模型——Template中的名称决议方式 (第七章)
2015-08-19 23:09
531 查看
Template中的名称决议方式 (Name Resolution within a Template)
必须能够区分以下两种意义,一种是C++ Standard所谓的"sope of the template",也就是"定义出template"的程序.另一种是C++ Standard所谓的"scope of the template instantiation",也就是"具现出template"的程序.第一种情况如下所示:
// 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> sr0;在ScopeRules template 中有两个foo()调用操作.在"scope of template definition"中,只有一个foo()函数声明位于scope内.然而在"scope of template instantiation"中,两个foo()函数声明都位于scope内,如果有一个函数调用操作:
// scope of the template instantiation sr0.invariant();那么在invariant()中调用的究竟是哪一个foo()函数实体呢?
// 调用的哪一个foo()函数实体 _member = foo(_val);在调用操作的那一点,程序中的两个函数实体是:
// scope of the template declaration extern double foo(double); // scope of the template instantiation extern int foo(int);而_val的类型是 int,那么选中的是哪一个呢?
结果选中的是直觉以外的那一个:
// scope of the template declaration extern double foo(double);Template中对于一个nonmember name的决议结果是根据这个name的使用是否与"用以具现出该template的参数类型"有关而决定的.如果其使用不相关,那么就以"scope of the template declaration"来决定name.如果其使用互有关联,那么就以"scope of the template instantiation"来决定name.在第一个例子中,foo()与用以具现ScopeRules的参数类型无关:
// the resolution of foo() is not dependent on the template argument _member = foo(_val);这是因为_val的类型是int;_val是一个"类型不会变动"的 template class member.也就是说,被用来具现出这个 template 的真正类型,对于_val的类型并没有影响.此外,函数的决议结果只和函数的原型有关,和函数的返回值没有关联.因此,_member的类型并不会影响哪一个foo()实体被选中.foo()的调用与 template 参数毫无关联.所以调用操作必须根据"scope
of the template declaration"来决议.在此scope中,只有一个foo()候选者.
下面是与类型相关的用法:
sr0.type_dependent();这个函数的内容如下:
return foo(_member);它究竟会调用哪一个foo()呢?
这个例子很清楚与 template 参数有关,因为该参数来决定_member的真正类型.所以这一次foo()必须在"scope of the template instantiation"中决议.
这意味着一个编译器必须保持两个scope contexts:
1."scope of the template declaration",用以专注于一般的 template class.
2."scope of the template instantiation",用以专注于特定的实体.
编译器的决议算法必须决定哪一个才是适当的scope,然后在其中搜寻适当的name.
Member Function的具现行为 (Member Function Instantiation)
对于 template 的支持,最困难的是 template function的具现.目前的编译器提供两个策略:一个是编译时期策略,程序代码必须在program text file中备妥可用;另一个是链接时期策略,有一些meta-complication工具可以导引编译器的具现行为.下面是编译器设计者必须回答的三个主要问题:
1.编译器如何找出函数的定义?
2.编译器如何能够只具现出用到的member functions?
3.编译器如何阻止member definition在多个.o文件中都被具现呢?
问题1:方法一是包含 template program text file,就好像它是个header文件一样.方法二是要求一个文件命名规则,例如可以要求在Point.h中发现的函数声明,其 template program text一定要放置于文件Point.c或Point.cpp中.
问题2:方法1就是忽略这个要求,把一个已经具现出的 class 的所有member functions都产生出来.方法二是仿真链接操作,检测看哪一个函数真正需要,然后只为它产生实体.
问题3:方法1就是产生多个实体,然后从链接器中提供支持,只留下其中一个实体,其余忽略.方法二是由使用者来导引"仿真链接阶段"的具现策略,决定哪些实体才是所需要的.
相关文章推荐
- C语言:内存地址分析 & sizeof和strlen用法总结
- C++11 第二章
- 最短路径弗洛伊德算法C语言实现__Floyd
- C++: 整型转字符串
- C语言不通过第三个变量交换a、b两数数值的技巧
- C语言二进制输出
- 03==C语言(运算符,基本数据类型)
- C语言速度优化之指针赋值与if判断
- C++中的智能指针
- C++ Primer Plus 第一章 预备知识
- mysql C语言API接口及实例
- 关于c++派生类构造函数的思考
- 深度优先算法:《啊哈!算法》一书中第四章“解救小哈”例子的 C++ 语言实现
- C语言中,二维数组中,p+1与*(p+1)的区别
- C语言字符串库函数的实现也是笔试题常考的题目,以下代码没有严格测试,只是简单的实现:
- OC中定义了一个结构体(struct),设置结构体的值
- 嵌入式SQL应用(C语言)
- C文件读写函数介绍
- malloc/free函数
- Effective C++学习笔记四(设计与声明)