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++对象模型——Template中的名称决议方式 (第七章)的更多相关文章

  1. C++ template —— 模板中的名称(三)

    第9章 模板中的名称------------------------------------------------------------------------------------------ ...

  2. IOS中的数据存储方式,特点,使用情况

    数据存储的核心都是写文件,主要有四种持久化方式:属性列表(Plist),对象序列化,SQLite数据库,CoreData. 存储Plist: 键值进行存储,不能存储对象.对象需要序列化编码才能写入文件 ...

  3. c++类模板template中的typename使用方法-超级棒

    转载:https://blog.csdn.net/vanturman/article/details/80269081 如有问题请联系我删除: 目录 起因 typename的常见用法 typename ...

  4. WCF中常用的binding方式

    WCF中常用的binding方式: BasicHttpBinding: 用于把 WCF 服务当作 ASMX Web 服务.用于兼容旧的Web ASMX 服务.WSHttpBinding: 比 Basi ...

  5. 表单提交中get和post方式的区别

    表单提交中get和post方式的区别有5点 1.get是从服务器上获取数据,post是向服务器传送数据. 2.get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一 ...

  6. html css <input> javaScript .数据类型 JS中的函数编写方式 BOM总结 DOM总结

    Day27  html css div 块标签. 特点: 独占一行,有高度和宽度 span 行元素. 特点:在同一行显示,当前行满了自动去下一行显示. 不识别高度和宽度 1.1.1.1 2.输入域标签 ...

  7. C++ - 模板(template)中typename的使用方法

    声明template参数时, 前缀关键字class和typename可以互换; 使用关键字typename标识嵌套从属类型名称, 但不需在基类列表和成员初始化列表内使用. 从属名称(dependent ...

  8. 通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span的脾气秉性(二)。 异步委托 微信小程序支付证书及SSL证书使用 SqlServer无备份下误删数据恢复 把list集合的内容写入到Xml中,通过XmlDocument方式写入Xml文件中 通过XDocument方式把List写入Xml文件

    通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的脾气秉性(二).   前言 读完上篇<通俗易懂,C#如何安全.高效地玩转任何种类的内存之Span的本质(一).>,相信大家对sp ...

  9. spring+hibernate 配置多个数据源过程 以及 spring中数据源的配置方式

    spring+hibernate 配置多个数据源过程 以及 spring中数据源的配置方式[部分内容转载] 2018年03月27日 18:58:41 守望dfdfdf 阅读数:62更多 个人分类: 工 ...

随机推荐

  1. [Testing][API][soapUI] 測試API 的軟體工具紀錄

    soapUI 測試API 的軟體工具紀錄 http://files.cnblogs.com/vincentmylee/soapUIScript%E9%9C%80%E8%A6%81%E8%B3%87%E ...

  2. apache hadoop 伪分布式安装

    1. 准备工作 1.1. 软件准备 1.安装VMWare 2.在VMWare上安装CentOS6.5 3.安装XShell5,用来远程登录系统 4.通过rpm -qa | grep ssh 检查cen ...

  3. 本地调试hbase

    需求说明 如果要本地调试Hbase程序,那么可以用本地连接集群的方式 配置文件 在maven里,配置文件cluster.properties放在target/classes里 cluster.prop ...

  4. 如何在linux使用nmap端口扫描工具扫描网段内开放的端口

    在另一个linux主机上,使用nmap命令即可 ,比如 我在1.1.1.2上开放了端口1111 -A -j ACCEPT 在1.1.1.1上执行 即可查到

  5. 梦想CAD控件COM接口文字样式

    增加文字样式 用户可以增加文字样式到数据库,并设置其字体等属性,具体实现c#代码如下: private void CreateText() { MxDrawApplication app = new ...

  6. 梦想CAD控件COM接口光栅图处理

    在CAD操作过程中,我们在设计绘图时,光栅图像也就是我们常说的图片,应用非常广泛,在CAD中可以直接插入光栅图像,并且可以对光栅图像进行裁剪.透明度调整等一些操作,在网页可以快速实现我们所需功能. 一 ...

  7. UVA - 208 Firetruck(并查集+dfs)

    题目: 给出一个结点d和一个无向图中所有的边,按字典序输出这个无向图中所有从1到d的路径. 思路: 1.看到紫书上的提示,如果不预先判断结点1是否能直接到达结点d,上来就直接dfs搜索的话会超时,于是 ...

  8. Ubuntu安装Foxit PDF阅读器

    最近使用Ubuntu自带的PDF阅读器,发现使用体验较差,打算安装FoxitReader(可能是我习惯了Foxit和Adobe) Foxit官网 对系统平台要求如下:(支持Linux) 继续摸索了一下 ...

  9. 爬虫之Requests库

    官方文档:http://cn.python-requests.org/zh_CN/latest/ 一.引子 import requests resp = requests.get("http ...

  10. SQLAlchemy-Utils

    由于sqlalchemy中没有提供choice方法,所以借助SQLAlchemy-Utils组件提供的choice方法. 安装: pip3 install sqlalchemy_utils 示例: f ...