第9章 模板中的名字
名字在大多数编程语言中都是最基本的概念,程序员用它来引用先前创建的对象。当C++编译器遇到一个名字,它要去查找并识别哪个对象被引用。从实现者角度来看,C++在一种强类型语言。考虑表达式X*Y:如果X和Y都是变量名,那么是乘法表达式;如果X是类型名,这条语句把Y声明为X类型的一个指针。
这个例子表明C++(和C一样)是上下文敏感的语言:如果没有上下文,一条程序指令很难被编译器理解。这与模板有什么关系呢?嗯,模板必须处理更多的上下文:(1)模板内部上下文;(2)模板实例化时的上下文;(3)模板实例化时模板参数的上下文。在C++中必须小心处理名字,对此你不应该感到惊讶。
9.1 名字分类学事实上C++的名字分类有很多种。为了便于记忆,我们提供了表格9.1和表格9.2描述了这些分类。幸运的是你只用熟悉下面2种主要的命名概念,就可以很好的理解C++模板中遇到的问题:
1、限定名:名字在作用域中被显式指示作用域解析运算符(
::)或者成员访问运算符(.或者
->)。例如:this
->count是限定名,而count不是(尽管count有可能是某个类的成员)。
2、依赖名:名字依赖于模板参数。例如:
std::vector<T>::iterator,如果T是模板参数,iterator就是依赖名;如果T是已知类型(比如int),iterator就是非依赖名。
表格 9.1. 名字分类学 (第一部分)
|
标识符 | 由字符、下划线(_)和数字组成的名字,不能以数字开头。有一些标识符是保留的,你不能在自己程序中引入它们(一种避免引入的笨方法是以_或者__作为前缀)。字符的概念很广泛,包括对非字母语言编码的特殊字符。 |
操作符类 | 关键字operator 后面跟着一个符号。例如operator new和operator []。很多操作符都是多义的,例如operator &可以是按位与运算,也可以是取地址运算。 |
转换类 | 指示用户定义的隐式类型转换。例如operator int&,我们可以把它转换成int类型的位与操作 |
模板类 | template后面跟着<>,里面是模板参数。例如List<T, int, 0>(严格讲,C++标准只允许简单的标识符为模板名,或许有争议说操作符类也是允许的;例如:operator+<X<int> >)。 |
非限定类 | 更一般的标识符。可以是上面几类(标识符、操作符类、转换类或模板类)或者是析构名(例如,像~Data 或 ~List<T, T, N>之类的符号)。 |
限定类 | 非限定类前面加上类或者名字空间限定,或者全局作用域解析运算符。注意一个名字本身可以是限定的,例如::X, S::x, Array<T>::y, and ::N::A<T>::z。 |
限定名 | 这个名词在标准中是没有的,我们用它来表示执行限定查找的名字。特定情况下,就是限定标识或者在非限定标识前面显式使用成员访问运算符(. 或者 ->)。例如S::x, this->f, 和 p->A::m。然而,除了class_mem 和this->class_mem在上下文环境中是等同的情况下不需要限定名,其他情况下必须显式使用成员访问运算符。 |
非限定名 | 非限定标识不是非限定名。这也不是一个标准中的术语,但是相当于执行非限定查找中的名字。 |
表格 9.2. 名字分类学 (第二部分)
|
名字 | 限定或者非限定的名字。 |
依赖名 | 名字依赖于模板参数。任何含有模板参数的限定或者非限定名字都是依赖名。此外,成员访问操作符(.或->) 修饰的限定名 ,如果操作符左边的表达式类型依赖于模板参数,那么这个限定名是依赖的。尤其这种情况:this->b中的b在模板中便是依赖名。最后,ident(x, y, z)调用形式中的ident当且仅当参数表达式中有类型依赖于模板参数。 |
非依赖名 | 不符合上面描述的名字就不是依赖名。 |
上面这些名词通常用来描述C++模板中的问题,通读一边是很有用的,我们可以熟悉这些名词,但没有必要记住每个名词确切的意思。需要的时候,我们可以通过索引很容易的查阅。
posted on 2006-04-08 11:38
万连文 阅读(1205)
评论(0) 编辑 收藏 引用 所属分类:
模板