第二章

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<intvoid> 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. 将此模板实例静态成员变量做类似外部变量的处理,即在汇编代码中为该变量临时分配一个内存地址,但在目标文件中标记该地址所关联的变量名及连接属性等,一边在随后有链接器修改地址,以正确的实现多个模板实例共享同一内存地址。

posted @ 2014-11-14 11:13  小超乐乐  阅读(156)  评论(0)    收藏  举报