第二章
1. 类型无关的数据结构
在一个类模板内出现的自身模板名,等价于该模板被调用时所产生的实例。
|
1
2
3
4
5
6
|
template <typename T = int>struct list_node{ T value; list_node *next; //此处list_node等价于list_node<T>} |
如果类模板参数有默认值,则在实参列表中可将其省略。如果所有参数都有默认值,则模板参数列表可以省略,但尖括号不能省。
|
1
|
list_node<> inode |
对于没有默认值得模板参数,只能为其一一赋值,而可以省略的仅限于列表最后有默认值的若干相邻参数。
2.栈类模板
异质链表的作用更类似于元组(tuple),可以将一组数量已知、类型已知切不同的数据组合在一起并且在不同函数间传递。
异质链表的例子。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
template<typename T, typename N>struct hetero_node{ T value; N* next; hetero_node(T const &v, N *n):value(v), next(n){}}template<typename T, typename N>hetero_node<T, N>* push(T const &v, N *n){ return new hetero_node<T, N>(v, n);}template<typename T, typename N>N* pop(hetero_node<T, N> *head){ N *next = head->next; delete head; return next;}int main(){ typedef hetero_node<int, void> node_0; typedef hetero_node<char, node_0> node_1; typedef hetero_node<std::string, node_1> node_2; //嵌套调用push模板以构造三元组 node_2 *p2 = push(std::string("Awesome!"), push('a', push(1, (void*)0))); //通过next成员可以访问到三元组中任意成员 std::cout << p2->value << ", " << p2->next->value << ", " << p2->next->next->value << std::endl; pop(pop(pop(p2))); return 0;} |
用异质链表构造多元组需要各个节点的成员变量next来保持元组数据间的联系,next指针所占内存空间形成额外的储存开销。另外的一种实现方式。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
template<typename T, typename N>struct tuple{ T value; N next; tuple(T const &v, N *n):value(v), next(n){}}template<typename T, typename N>tuple<T, N> push(T const &v, N const &n){ return new tuple<T, N>(v, n);}int main(){ typedef tuple<int, void> node_0; typedef tuple<char, node_0> node_1; typedef tuple<std::string, node_1> node_2; //嵌套调用push模板以构造三元组 node_2 *p2 = push(std::string("Awesome!"), push('a', push(1, (void*)0))); //通过next成员可以访问到三元组中任意成员 std::cout << p2.value << ", " << p2.next.value << ", " << p2.next.next.value << std::endl; return 0;} |
类模板tuple与前面介绍的hetero_node很类似,不同之处却在于hetero_node中的指针成员变量,消除了hetero_node构成的已知量表存储元组时的额外存储开销。但是,在嵌套调用push函数模板构造元组时,每调用一次push就被复制一次。
也可以使用类来实现元组,可以避免嵌套。
3. 成员函数模板
成员函数模板的参数不能与类模板参数相同,否则会造成命名冲突。
4.类模板的静态成员
类模板的静态成员变量是所有同类型的模板实例共享的一块数据。
C++编译器会对类模板静态成员变量做特殊处理。
代码必须按照C++标准的要求,将类模板静态成员变量的实现与类模板实现放在同一可见范围内。通常,将静态成员变量的实现写在类模板实现之后。
只要静态成员变量的模板与其类模板同时可见,编译器就可针对类模板的静态成员变量做特殊处理:
i. 在目标文件中写入类模板实例中静态成员变量的初始值。
ii. 将此模板实例静态成员变量做类似外部变量的处理,即在汇编代码中为该变量临时分配一个内存地址,但在目标文件中标记该地址所关联的变量名及连接属性等,一边在随后有链接器修改地址,以正确的实现多个模板实例共享同一内存地址。

浙公网安备 33010602011771号