0. 简介Introduction
名称是绝大数编程语言最基础的概念。程序员可以通过名称来引进先前构建的物体(entity)。当编译器碰到一个名称,它必须搜寻这个名称引用的哪个物体。从编译器实现者的角度看,C++名称体系非常复杂。考虑语句:x*y; ,如果x和y是变量名称,则这个语句表示一个乘法;但是如果x是个类型名称,则这个语句声明一个指针y, 指向类型为x的物体。
这个例子说明C++、c是一种所谓上下文敏感context-sensitive的语言:如果没有上下文背景,就不能知道某一构件construct的具体含义。这和template有什么关系?template是一种与上下文背景联系更深广的构件,这些上下文背景包括:
1)templates出现的位置和方式;
2)templates被实例化的位置和方式;
3)用以实例化template的那些模板实参的上下文背景。
因此C++中必须小心处理名称。
1.名称分类学Name Taxonomy
C++以各式各样的方法对名称分类。为帮助你理解如此多的术语,这里提供了表1和表2,描述了这些分类。幸运的是,如果能够熟悉两个最主要的命名概念,就能洞察大多数C++templates问题。
1)受饰名称qualified name:其含义是:以scope resolution运算子::或member access运算符(. 或->)指明该名称所谓作用域。例如this->count是一个受饰名称,但count不是。
2) 受控名称dependent name:其含义是:它在某些方面受控依赖于某个template parameter。如果T是个template parameter,std::vector<T>::iterator就是一个受控名称;但如果T是已知类型(例如int), std::vector<T>::iterator是一个非受控名称(nondependent name)。
表1 名称分类表
分类 | 解释和注意 |
标识符Identifier | 一个不能以数字开头不间断的字母、下划线和数字组成的序列。 |
运算子函数标识符 | 关键字operator后跟一个表示某项操作的符号。例如operator new operator [] |
转型函数标识符 | 用来表示使用者自定义的转型函数,如operator int&,它还有另一种费解的写法:operator int bitand |
模板标识符 | 模板名称之后跟着角括号括起来的template argument list,例如,List<T, int, 0>. |
非受饰标识符 | 这是标识符的泛化 |
受饰标识符 | 当一个标识符被class名称或namespace名称或global范围算子修饰后,就成为受修饰标识符,如::x, S::x |
受饰名称 | 这是一个在成员访问算子如. 或.->后面的标识符,如this->f, p->A::m |
非修饰名称 | 不是受修饰的名称,的非修饰标识符,就是非修饰名称 |
表2 名称分类表
分类 | 解释和注意 |
名称Name | 既可以是修饰名称,也可以非受饰名称 |
受控名称Dependent name | 在某些方面受控于某个template parameter |
非受控名称Nondependent name | 不是受控名称的名称 |
2. 名称查询lookup names
3. 解析模板Parsing Templates
4.衍生与类模板Derivation and Class Templates
5.小结 Summary